【发布时间】:2013-01-24 01:31:57
【问题描述】:
Java 模运算符% 基于截断除法(请参阅Wikipedia: Modulo operation)。
-
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,有时在 [a,n[ 中获取唯一整数 r 很有用,它与 a 模 @987654346 一致@。
问题
在 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) 轻松地对值(最接近的整数)进行下限 -
@Killrawr
Math.floor()比上述任何解决方案都差。 -
@Killrawr
a - n * (int)Math.floor((double)a/n);在数学上对于底模是正确的,但效率不高,也不通用。 -
@boumbh 你想要哪种行为?
(-5)magicmod(-3)应该给什么?-2或2? -
哈哈我还没有尝试过问题中的任何解决方案(以寻找改进)。但是无论如何感谢UmNyobe(+1代表)的澄清。通常我在数学库中找到的大多数函数都很棒,尽管像 cos/sin/tan/pow/sqrt/log/exp。但我并没有真正用地板/天花板功能编写任何东西(对不起,我帮不上什么忙)。
标签: java operators modulo modulus negative-number