Reputation: 25
I am having a problem with the Java modulus function.
For some reason the computer has -3 % 26
equal to -3 when it should equal 23, since the lowest multiple of 26 less than -3 is -26 and -3 - -26
is 23.
Also, if you add 26 to -3, which is essentially adding a modulus of 0, then the result should not change, and the result should become 23. Can anyone explain why Java has -3 % 26 == -3
and not 23 and how to fix this problem?
Upvotes: 0
Views: 1767
Reputation: 37645
Mathematicians usually define the remainder when the integer a
is divided by the positive integer b
to be a - bq
, where the quotient q
is floor(a ÷ b)
. According to this definition, the remainder when -3
is divided by 26
is 23
as you rightly say.
However, the Java programming language defines remainder differently. Instead of using floor
(i.e. rounding towards negative infinity), the rounding is done towards zero. This doesn't change the answer for positive values, but for negative a
and positive b
the Java answer is b
smaller than the mathematicians' answer (unless b
divides exactly into a
, in which case everyone agrees the answer is 0
). Therefore -3 % 26 == 23 - 26 == -3
.
Java programmers usually call %
the remainder operator, but you are correct that it is also commonly called the modulus operator. In Visual Basic it's even written Mod
, but it works the same as %
in C / C# / Java etc.
In my opinion, rounding towards zero rather than negative infinity is a mistake and it only makes life harder. For example, to test if an integer n
is odd you ought to be able to do if (n % 2 == 1)
, but that doesn't work because if n
is negative and odd the answer is -1
. I don't know which language did it first, but the same mistake has been repeated by C, C++, C# and Java. Languages that do integer division correctly (in my view) include Python, Ruby and Haskell.
In Java 8, methods have been added to the Math
class for division where the rounding is towards negative infinity rather than zero. The methods are.
Math.floorDiv(int, int)
Math.floorMod(int, int)
Math.floorDiv(long, long)
Math.floorMod(long, long)
Math.floorMod(-3, 26)
returns 23
as you wanted.
Upvotes: 3
Reputation: 6084
In the modulus logic the resulting values should be the remainder to get to 0. So when you say -3%26, the result is -3 as to add 3 to get to 0.
Upvotes: 5