Kotlin 负模 returns 负值

Kotlin negative modulo returns negative value

Kotlin 中,我已经看到对于函数 a.mod(n),如果 a 为负,则结果为负。这不是模应该做的。我该怎么做才能始终保持正模?

例如:

(-2).mod(9)

returns -2 应该是 7

在 kotlin 1.1 版本中,mod 已被弃用,因为它正在计算除法的余数,这可能是负数。这就是为什么他们更改为 rem,与其功能更相似的名称。如果你想要 Kotlin 和大多数语言中的模函数,你可以使用这个:

r = (a).rem(n)
if (r < 0) r += n

正如 Paul Lammertsma 在评论中提到的那样,最佳答案是 Math.floorMod(),因为它在数学上是最正确的:它总是 returns 介于零(含)和除数(不含)之间的值, 并且不管一个或两个参数是否为负数都这样做。

翻转所有输入和输出的符号甚至是不变的:

Math.floorMod(11, 9) => 2
Math.floorMod(-11, -9) => -2

Math.floorMod(-11, 9) => 7
Math.floorMod(11, -9) => -7

Math.floorMod 从 JDK 1.8 开始可用。

在 Kotlin 1.5 中,行为发生了变化,并且 (-11).mod(9) == 7 正如 OP 所预期的那样。一般来说,mod的结果与除数的符号相同。

注意运算符 % 仍然是 rem,所以 (-11) % 9 == -2.

来源:https://blog.jetbrains.com/kotlin/2021/04/kotlin-1-5-0-rc-released/

对于轮播数组访问,有一个解决方案适用于 % 或 rem,只要负值不低于数组的大小即可。 因此,如果您在大小为 16

的数组中旋转

( 11 + 16 ) % 16) => 11

( -11 + 16 ) % 16) => 5

( -15 + 16 ) % 16) => 1

( -16 + 16 ) % 16) => 0

( 0 + 16 ) % 16 => 0

不需要调用额外的函数,所以我预计这会更快(未测试)。

( 16 + 16 ) % 16 => 0