最好的方式使Java的模数行为应该与负数?

在Java中,当你这样做

a % b 

如果a是负数,它将返回一个负数结果,而不是像应该的那样缠绕到b。 解决这个问题的最好方法是什么? 我唯一能想到的就是

 a < 0 ? b + a : a % b 

它的行为应该如下:%b = a – a / b * b; 即剩下的。

你可以做(​​a%b + b)%b


这个expression式的作用是(a % b)的结果必然低于b ,不pipea是正数还是负数。 因为(a % b)-b0之间的负值, (a % b + b)必然低于b并且是正值,所以添加b需要注意a的负值。 如果a是正数,那么最后一个模是在那里,因为如果a是正数(a % b + b)会比b 。 因此, (a % b + b) % b b再次变成小于b (并且不影响负a值)。

从Java 8开始,可以使用Math.floorMod(int x,int y)和Math.floorMod(long x,long y) 。 这两种方法都可以得出和Peter的答案一样的结果。

 Math.floorMod( 2, 3) = 2 Math.floorMod(-2, 3) = 1 Math.floorMod( 2, -3) = -1 Math.floorMod(-2, -3) = -2 

对于那些不使用(或不能使用)Java 8的人来说,番石榴来到Gumava 11.0以后的IntMath.mod() 。

 IntMath.mod( 2, 3) = 2 IntMath.mod(-2, 3) = 1 

一个警告:不像Java 8的Math.floorMod(),除数(第二个参数)不能是负数。

在数论中,结果总是正面的。 我猜想这在计算机语言中并不总是如此,因为并不是所有的程序员都是math家。 我的两分钱,我会认为这是一个语言的devise缺陷,但你现在不能改变它。

= MOD(-4,180)= 176 = MOD(176,180)= 176

因为180 *(-1)+ 176 = -4与180 * 0 + 176 = 176相同

使用这里的时钟例子, http: //mathworld.wolfram.com/Congruence.html你不会说duration_of_time mod cycle_length是-45分钟,你会说15分钟,即使这两个答案满足基本方程。

我更喜欢这个expression:

 a < 0 ? b - (-a) % b : a % b 

这可能会或可能不会比其他公式[(a%b + b)%b]更快)来思考它。 它包含一个通常与现代处理器不兼容的分支,但使用一个较less的模运算。

其实它肯定会慢一些。