减去 2 个多头时的溢出检测



我一直在浏览 Apache 的常用数学库链接

在下面的代码片段行中,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;
}

所以,Long.MIN_VALUE == -(Long.MAX_VALUE + 1) == -Long.MAX_VALUE - 1,特别是Long.MIN_VALUE == -Long.MIN_VALUE。因此,如果a >= 0,加/减Long.MIN_VALUE总是会产生溢出。这意味着这是一个特殊情况,该方法必须测试(A),并且只有在a < 0(B)时才执行实际减法。由于我们已经测试了可能的溢出,我们可以简单地做(C)。

MIN_VALUE

减去尽可能小的数字与MAX_VALUE添加最大数字相同。实际上它甚至像在java中一样MAX_VALUE+1long都是有符号的,0像正数一样编码,所以正数比负数少一个。

这就是为什么a必须小于 0 才能使此减法(加法)起作用 (B)。但是,如果a小于 0 并且 b 是可能的最小数字。a - b总是成功的。(三)

之所以甚至检查这种特殊情况(A),是因为这种情况,小可能数的绝对值比最大可能数大一,因此addAndCheck(a, -b, LocalizedFormats.OVERFLOW_IN_ADDITION);线将在位置-b

相关内容

  • 没有找到相关文章

最新更新