我一直在浏览Apache的常用数学库Link
在下面的代码片段中,A,B,C对我没有意义。有人可以对此有所了解吗?
public static long subAndCheck(long a, long b) throws MathArithmeticException {
long ret;
if (b == Long.MIN_VALUE) { ----------A
if (a < 0) { --------------------B
ret = a - b; ----------------C
} else {
throw new MathArithmeticException(LocalizedFormats.OVERFLOW_IN_ADDITION, a, -b);
}
} else {
// use additive inverse
ret = addAndCheck(a, -b, LocalizedFormats.OVERFLOW_IN_ADDITION);
}
return ret;
}
private static long addAndCheck(long a, long b, Localizable pattern) throws MathArithmeticException {
final long result = a + b;
if (!((a ^ b) < 0 || (a ^ result) >= 0)) {
throw new MathArithmeticException(pattern, a, b);
}
return result;
}
答案 0 :(得分:3)
所以,vmlinux
,特别是Long.MIN_VALUE == -(Long.MAX_VALUE + 1) == -Long.MAX_VALUE - 1
。因此,如果Long.MIN_VALUE == -Long.MIN_VALUE
,添加/减去a >= 0
将始终产生溢出。这意味着该方法必须测试(A)并且仅在Long.MIN_VALUE
(B)时执行实际减法的特殊情况。由于我们已经测试了可能的溢出,我们可以简单地做(C)。
答案 1 :(得分:1)
减去最小可能的数字MIN_VALUE
与添加最大数字MAX_VALUE
相同。实际上它甚至是MAX_VALUE+1
,因为在java中,long
都被签名,0被编码为正数,因此正数少于负数。
这就是为什么a
必须小于0才能使这个减法(加法)工作(B)。但是,如果a
小于0且b是可能的最小数字。 a - b
总是会成功的。 (C)
为什么甚至检查这种特殊情况(A)的原因是,因为这种情况,尽可能小的绝对值比最大可能的数字大一个,因此行addAndCheck(a, -b, LocalizedFormats.OVERFLOW_IN_ADDITION);
会失败在-b