How does java do modulus calculations with negative numbers?
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);
Comments
-
Jakir00 almost 2 years
Am I doing modulus wrong? Because in Java
-13 % 64
evaluates to-13
but I want to get51
. -
Pascal Cuoq over 13 yearsThe question is "why does Java give me
-13 % 64 = 51
when I was expecting-13
?". -
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 almost 10 yearsThis 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 over 9 years@ruslik You can also do:
((x % k) + k) % k
. (Though yours is probably more readable.) -
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 over 9 yearsIn 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 almost 9 yearsThe mathematically sane behavior is available in Java 8: Math.floorMod
-
ceprateek almost 9 years@Xaver Kapeller: How can 51 and -13 both can be correct ? Java would return just one value ..
-
NightShadeQueen over 8 yearsIn which version was this change made?
-
vsn harish rayasam over 8 yearsIn java 7 it clearly mentions that mod will have sign of numerator :)
-
Oz Edri over 8 yearsSomething in their 15.17.3. Remainder Operator % examples isn't clear.
int result = (-5) % 3;
gives -2int 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 orint result = (((-a) % b) + b) % b;
for positive or negative a. -
Oz Edri over 8 yearsSomething 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 orint result = (((-a) % b) + b) % b;
for positive or negative a -
starblue over 8 yearsYour 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 over 8 yearsI 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 be2
-
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 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 over 7 yearsIn the context of Java (as per question tag) this answer is essentially "wrong". Given the expression
x % y
, A) ifx
is negative the remainder is negative, iex % y == -(-x % y)
. B) the sign ofy
has no effect iex % y == x % -y
-
user207421 almost 7 years@NightShadeQueen It was never changed.
-
user207421 almost 7 years@XaverKapeller How can an answer that documents what Java actually does possibly be wrong?
-
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 almost 5 years@Caner I didn't understand this, How could both be same?