Hey,
Ich schreibe gerade eine Klasse für Operationen in einem finite field.
Ich habe auch alle Operationen implementiert bekommen, allerdings nicht perfekt.
Ich möchte das jede der Operationen:
Meine Unit-Tests (Ich verwende XUnit) sehen wie folgt aus:
Nicht alle unit tests passen. Ich habe Probleme mit negativen Werten und mit overflows.
hat jemand eine Idee wie ich meine Methoden anpassen kann damit alle Tests passen?
Bisher:
Ich schreibe gerade eine Klasse für Operationen in einem finite field.
Ich habe auch alle Operationen implementiert bekommen, allerdings nicht perfekt.
Ich möchte das jede der Operationen:
- Overflowschutz hat, d.h. sollte die
int.MaxValue
überschritten, bzw dieint.MinValue Grenze
unterschritten werden. - Wenn möglich die BigInteger Klasse vermeiden.
- Der Umgang mit negativen Werten soll funktionieren - und genau da haperts.
C#-Quellcode
- public class FiniteFieldArithmetic
- {
- /// <summary>
- /// The modulo or the size of the finite field
- /// </summary>
- private static int _modulo;
- /// <summary>
- /// Initializes the finite field operations for a specified modulo
- /// </summary>
- /// <param name="modulo">The modulo</param>
- public FiniteFieldArithmetic(int modulo)
- {
- _modulo = modulo;
- }
- /// <summary>
- /// Modular addition (overflow safe)
- /// </summary>
- /// <param name="a">The first number</param>
- /// <param name="b">The second number</param>
- /// <returns>The sum under the specified modulo</returns>
- public int Add(int a, int b)
- {
- a %= _modulo;
- b %= _modulo;
- int sum = a + b;
- return (sum >= _modulo || sum < a) ? sum - _modulo : sum;
- }
- /// <summary>
- /// Modular subtraction (overflow safe)
- /// </summary>
- /// <param name="a">The first number</param>
- /// <param name="b">The second number</param>
- /// <returns>The difference under the specified modulo</returns>
- public int Sub(int a, int b)
- {
- a %= _modulo;
- b %= _modulo;
- int diff = a - b;
- return (a < b) ? diff + _modulo : diff;
- }
- /// <summary>
- /// Modular multiplication
- /// </summary>
- /// <param name="a">The first number</param>
- /// <param name="b">The second number</param>
- /// <returns>The product under the specified modulo</returns>
- public int Mul(int a, int b)
- {
- if (a >= _modulo)
- a %= _modulo;
- if (b >= _modulo)
- b %= _modulo;
- int c = a * b / _modulo;
- return (a * b - c * _modulo) % _modulo;
- }
- }
Meine Unit-Tests (Ich verwende XUnit) sehen wie folgt aus:
C#-Quellcode
- public class FiniteFieldArithmeticTest
- {
- [Theory]
- [InlineData(2, 5, 3, 1)] // Normal Values
- [InlineData(-2, 5, 3, 0)] // Normal Value, a is negative
- [InlineData(2, -5, 3, 0)] // Normal Value, b is negative
- [InlineData(int.MaxValue, 1337, 420, 204)] // Upper bound overflow check with value A
- [InlineData(1337, int.MaxValue, 420, 204)] // Upper bound overflow check with value B
- [InlineData(int.MinValue, -1337, 420, 215)]// Lower bound overflow check with value A
- [InlineData(-1337, int.MinValue, 420, 215)] // Lower bound overflow check with value B
- [InlineData(1337, 420, int.MaxValue, 1757)] // Highest possible modulus
- [InlineData(int.MaxValue, int.MaxValue, 1337, 527)] // Upper bound Overflow check with value A and B
- [InlineData(int.MinValue, int.MinValue, 1337, 808)] // Upper bound Overflow check with value A and B
- public void FiniteFieldAddTest(int a, int b, int m, int expectedResult)
- {
- var finiteField = new FiniteFieldArithmetic(m);
- var result = finiteField.Add(a, b);
- Assert.Equal(expectedResult, result);
- }
- [Theory]
- [InlineData(2, 5, 3, 0)] // Normal Values
- [InlineData(-2, 5, 3, 2)] // Normal Value, a is negative
- [InlineData(2, -5, 3, 1)] // Normal Value, b is negative
- [InlineData(int.MaxValue, 1337, 420, 50)] // Upper bound overflow check with value A
- [InlineData(1337, int.MaxValue, 420, 370)] // Upper bound overflow check with value B
- [InlineData(int.MinValue, -1337, 420, 369)]// Lower bound overflow check with value A
- [InlineData(-1337, int.MinValue, 420, 51)] // Lower bound overflow check with value B
- [InlineData(int.MaxValue, int.MaxValue, 1337, 0)] // Upper bound Overflow check with value A and B
- [InlineData(int.MinValue, int.MinValue, 1337, 0)] // Upper bound Overflow check with value A and B
- public void FiniteFieldSubTest(int a, int b, int m, int expectedResult)
- {
- var finiteField = new FiniteFieldArithmetic(m);
- var result = finiteField.Sub(a, b);
- Assert.Equal(expectedResult, result);
- }
- [Theory]
- [InlineData(2, 5, 3, 1)] // Normal Values
- [InlineData(-2, 5, 3, 2)] // Normal Value, a is negative
- [InlineData(2, -5, 3, 2)] // Normal Value, b is negative
- [InlineData(int.MaxValue, 1337, 420, 119)] // Upper bound overflow check with value A
- [InlineData(1337, int.MaxValue, 420, 119)] // Upper bound overflow check with value B
- [InlineData(int.MinValue, -1337, 420, 196)]// Lower bound overflow check with value A
- [InlineData(-1337, int.MinValue, 420, 196)] // Lower bound overflow check with value B
- [InlineData(int.MaxValue, int.MaxValue, 1337, 911)] // Upper bound Overflow check with value A and B
- [InlineData(int.MinValue, int.MinValue, 1337, 102)] // Upper bound Overflow check with value A and B
- public void FiniteFieldMulTest(int a, int b, int m, int expectedResult)
- {
- var finiteField = new FiniteFieldArithmetic(m);
- var result = finiteField.Mul(a, b);
- Assert.Equal(expectedResult, result);
- }
- }
Nicht alle unit tests passen. Ich habe Probleme mit negativen Werten und mit overflows.
hat jemand eine Idee wie ich meine Methoden anpassen kann damit alle Tests passen?
Bisher:
C# Developer
Learning C++
Learning C++