Java 取模运算符 %
基于截断除法(参见 维基百科:模运算)。
5%3
的结果为2
(注意,5/3
的结果为1
)5%(-3)
的结果为2
(注意,5/(-3)
的结果为-1
)(-5)%3
的结果为-2
(注意,(-5)/3
的结果为-1
)(-5)%(-3)
的结果为-2
(注意,(-5)/(-3)
的结果为1
)
在计算机科学中,给定两个整数 a
和 n
,n > 0
,有时需要获取唯一的整数 r
,它在 [a,n[
内与 a
模 n
同余。
问题
Java 中是否有一种高效的通用运算符/方法,符合此模数规范?
这是为了避免在需要时在每个项目中重写它...
其他信息
我在 stackoverflow 上找到了很多关于这个问题的帖子,大部分都混淆了不同的模数实现。如果您只关心负数取模运算的结果,则下面是一些基于 Java %
运算符的实现,可能会有用。
通用技巧
由于我们很少使用负除数,因此当 n > 0
时,此实现将返回欧几里得或向下取整的模数。
static int mod(int a, int n){
return a<0 ? (a%n + n)%n : a%n;
}
mod(5, 3)
的结果为2
mod(-5, 3)
的结果为1
欧几里得模运算
static int euclideanModulo(int a, int n){
return n<0 ? euclideanModulo(a, -n) : mod(a, n);
}
euclideanModulo( 5, 3)
的结果是2
euclideanModulo(-5, 3)
的结果是1
euclideanModulo( 5,-3)
的结果是2
euclideanModulo(-5,-3)
的结果是1
向下取整的模
static int flooredModulo(int a, int n){
return n<0 ? -flooredModulo(-a, -n) : mod(a, n);
}
flooredModulo(5,3)
产生2
flooredModulo(-5,3)
产生1
flooredModulo(5,-3)
产生-1
flooredModulo(-5,-3)
产生-2
Math.floor()
(JavaDocs)将值向下取整(最接近的整数)。 - classicjonesynzMath.floor()
比上面任何一种解决方案都要差。 - UmNyobea - n * (int)Math.floor((double)a/n);
在数学上是正确的,用于向下取整的模运算,但不是高效的,也不是通用的。 - boumbh(-5)magicmod(-3)
应该返回什么?-2
还是2
? - UmNyobearray[mod(i++, array.length)]
。这不是一个紧急问题,更像是我“个人修养”的好奇问题。 - boumbh