How does java do modulus calculations with negative numbers?

128,559

Solution 1

Both definitions of modulus of negative numbers are in use - some languages use one definition and some the other.

If you want to get a negative number for negative inputs then you can use this:

int r = x % n;
if (r > 0 && x < 0)
{
    r -= n;
}

Likewise if you were using a language that returns a negative number on a negative input and you would prefer positive:

int r = x % n;
if (r < 0)
{
    r += n;
}

Solution 2

Since "mathematically" both are correct:

-13 % 64 = -13 (on modulus 64)  
-13 % 64 = 51 (on modulus 64)

One of the options had to be chosen by Java language developers and they chose:

the sign of the result equals the sign of the dividend.

Says it in Java specs:

https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.17.3

Solution 3

Are you sure you are working in Java? 'cause Java gives -13 % 64 = -13 as expected. The sign of dividend!

Solution 4

Note that this answer was for a previous, different version of the question.

Your result is wrong for Java. Please provide some context how you arrived at it (your program, implementation and version of Java).

From the Java Language Specification

15.17.3 Remainder Operator %
[...]
The remainder operation for operands that are integers after binary numeric promotion (§5.6.2) produces a result value such that (a/b)*b+(a%b) is equal to a.
15.17.2 Division Operator /
[...]
Integer division rounds toward 0.

Since / is rounded towards zero (resulting in zero), the result of % should be negative in this case.

Solution 5

you can use

(x % n) - (x < 0 ? n : 0);
Share:
128,559
Jakir00
Author by

Jakir00

Software engineer from Seattle, Washington.

Updated on July 10, 2022

Comments

  • Jakir00
    Jakir00 almost 2 years

    Am I doing modulus wrong? Because in Java -13 % 64 evaluates to -13 but I want to get 51.

  • Pascal Cuoq
    Pascal Cuoq over 13 years
    The question is "why does Java give me -13 % 64 = 51 when I was expecting -13?".
  • Admin
    Admin over 13 years
    @pascal: java gives you the right definition in math and the way it has been implemented to do that not the thing you expecting from it.
  • partlov
    partlov almost 10 years
    This doesn't work good if n is negative. If you user same example from Java 7 Lang Spec (Section 15.17.3): (-5) % (-3) = -2. Adding -3 will not work. You should add absolute value of n if you want to be sure that value is positive.
  • SubParProgrammer
    SubParProgrammer over 9 years
    @ruslik You can also do: ((x % k) + k) % k. (Though yours is probably more readable.)
  • Fabyen
    Fabyen over 9 years
    @XaverKapeller, no ! Many people pointed out that mathematically speaking -13 and 51 are correct. In Java, -13 is the expected answer, and it's what I got too, so I don't know how submitter got 51, it's mystery. Mode details about the context could help to answer correctly this question.
  • Fabyen
    Fabyen over 9 years
    In Java negative modulo does not change anything, if you use an Abs() anyway, just write r = x % abs(n). I don't like if statement, I'd rather write r = ((x%n) + n) % n. Concerning power of 2 modulo (2,4,8,16,etc..) and positive answer, consider binary mask r = x & 63.
  • Jesse Glick
    Jesse Glick almost 9 years
    The mathematically sane behavior is available in Java 8: Math.floorMod
  • ceprateek
    ceprateek almost 9 years
    @Xaver Kapeller: How can 51 and -13 both can be correct ? Java would return just one value ..
  • NightShadeQueen
    NightShadeQueen over 8 years
    In which version was this change made?
  • vsn harish rayasam
    vsn harish rayasam over 8 years
    In java 7 it clearly mentions that mod will have sign of numerator :)
  • Oz Edri
    Oz Edri over 8 years
    Something in their 15.17.3. Remainder Operator % examples isn't clear. int result = (-5) % 3; gives -2 int result = (-3) % 5; gives -3 In general, int result = (-a) % b; gives the right answer when |-a| > b In order to get the proper result when |-a| < b we should wrap the divisor. int result = ((-a) % b) + b; for negative a or int result = (((-a) % b) + b) % b; for positive or negative a.
  • Oz Edri
    Oz Edri over 8 years
    Something in their 15.17.3. Remainder Operator % examples isn't clear. int result = (-5) % 3; gives -2. int result = (-3) % 5; gives -3. In general, int result = (-a) % b; gives the right answer when |-a| > b. In order to get the proper result when |-a| < b we should wrap the divisor. int result = ((-a) % b) + b; for negative a or int result = (((-a) % b) + b) % b; for positive or negative a
  • starblue
    starblue over 8 years
    Your comment is quite unclear. The section defines the correct result, and the examples agree with that definition. For your example (-3) % 5 the correct result according to the definition is -3, and a correct implementation of Java should produce that result.
  • Oz Edri
    Oz Edri over 8 years
    I guess I didn't explain myself correctly. What I meant by "the right answer" when |-a|<b is that in order to get a positive result we should "wrap" the given result from a%b by adding b to it. In my example, (-3)%5 indeed gives -3, and if we want the positive remainder we should add 5 to it, and then the result will be 2
  • Joschua
    Joschua almost 8 years
    @JohnKurlak You version works like this: 4 % 3 = 1 OR 4 % -3 = -2 OR -4 % 3 = 2 OR -4 % -3 = -1 but the one from ruslik works like this: 4 % 3 = 1 OR 4 % -3 = 1 OR -4 % 3 = -4 OR -4 % -3 = 2
  • SubParProgrammer
    SubParProgrammer almost 8 years
    @Joschua Thanks for pointing this out. My code is helpful for when you want the modulus result to be in the range of [0, sign(divisor) * divisor) instead of [0, sign(dividend) * divisor).
  • Bohemian
    Bohemian over 7 years
    In the context of Java (as per question tag) this answer is essentially "wrong". Given the expression x % y, A) if x is negative the remainder is negative, ie x % y == -(-x % y). B) the sign of y has no effect ie x % y == x % -y
  • user207421
    user207421 almost 7 years
    @NightShadeQueen It was never changed.
  • user207421
    user207421 almost 7 years
    @XaverKapeller How can an answer that documents what Java actually does possibly be wrong?
  • Xaver Kapeller
    Xaver Kapeller almost 7 years
    @EJP I think 3 years ago when I wrote this I was dumb enough to value mathematical accuracy more than the simple reality of how java deals with this. Thanks for reminding me to remove my stupid comment :D
  • Kishore Kumar Korada
    Kishore Kumar Korada almost 5 years
    @Caner I didn't understand this, How could both be same?