Search code examples
c#numericbigintegermodulosystem.numerics

Numerics BigInteger.Remainder (Mod) doesn't work with negative divisors


Consider the following equations:

10 %  3 =  1
10 % -3 = -2

10001 %  30 =  11
10001 % -30 = -19

C#'s System.Numerics.BigInteger Seems to produce positive results for negative divisors, as if something like Abs(divisor) has been used in the calculation; for example:

10 % -3

BigInteger left = 10;
BigInteger right = -3;

Console.WriteLine(left % right); // 1, but should be -2

10001 % -30

BigInteger left = 10001;
BigInteger right = -30;

Console.WriteLine(left % right); // 11, but should be -19

Why is this? Is this a bug?


Solution

  • Modulus/remainder operations can have different behaviors with negative operands in different programming languages.

    .NET consistently follows the convention specified in the BigInteger documentation:

    The sign of the value returned by the modulus operation depends on the sign of dividend: If dividend is positive, the modulus operation returns a positive result; if it is negative, the modulus operation returns a negative result. The behavior of the modulus operation with BigInteger values is identical to the modulus operation with other integral types.

    So you should see the same behavior with int, long etc - but that may be different behavior to other platforms (e.g. Wolfram Alpha). It happens to be the same in .NET as in Java - from the JLS remainder operator docs:

    It follows from this rule that the result of the remainder operation can be negative only if the dividend is negative, and can be positive only if the dividend is positive. Moreover, the magnitude of the result is always less than the magnitude of the divisor.