最好的方式使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)
是-b
和0
之间的负值, (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的模运算。
其实它肯定会慢一些。