In Kotlin I have seen that for function a.mod(n)
, if a
is negative the result is negative. Which is not what modulo is supposed to do. What can I do to have always positive modulo?
For example:
(-2).mod(9)
returns -2
and should be 7
.
In Kotlin I have seen that for function a.mod(n)
, if a
is negative the result is negative. Which is not what modulo is supposed to do. What can I do to have always positive modulo?
For example:
(-2).mod(9)
returns -2
and should be 7
.
The best answer is Math.floorMod()
as Paul Lammertsma mentioned in a comment, since it is the most mathematically correct: It always returns a value between zero (inclusive) and the divisor (exclusive), and does so regardless of whether either or both arguments are negative.
It's even invariant across flipping the signs of all the inputs and output:
Math.floorMod(11, 9) => 2
Math.floorMod(-11, -9) => -2
Math.floorMod(-11, 9) => 7
Math.floorMod(11, -9) => -7
Math.floorMod
is available since JDK 1.8.
In version kotlin 1.1 mod
is deprecated because it was calculating the remainder of the division, which can be negative. Thats why they changed to rem
, more similar name to its functionality. If you want a modulo function in Kotlin, and the majority of languages, you can use this:
r = (a).rem(n)
if (r < 0) r += n
In Kotlin 1.5 the behavior changed and (-11).mod(9) == 7
as OP expected. In general,the result of mod
will have the same sign as the divisor.
Note that operator %
is still rem
, so (-11) % 9 == -2
.
Source: https://blog.jetbrains.com/kotlin/2021/04/kotlin-1-5-0-rc-released/
For carousel array access there is a solution that works with % or rem as well as long as the negative is not below the size of the array. So if you rotate in an array with size 16
( 11 + 16 ) % 16) => 11
( -11 + 16 ) % 16) => 5
( -15 + 16 ) % 16) => 1
( -16 + 16 ) % 16) => 0
( 0 + 16 ) % 16 => 0
There is no need to call an extra function so this will be faster I expect (not tested).
( 16 + 16 ) % 16 => 0