更大。如果我有一个分配龙+长不超过Long.MAX_VALUE
Long c = a + b;
有没有一种简单的方法来检查a + b
并不是越大/比Long.MAX_VALUE
/Long.MIN_VALUE
小?
更大。如果我有一个分配龙+长不超过Long.MAX_VALUE
Long c = a + b;
有没有一种简单的方法来检查a + b
并不是越大/比Long.MAX_VALUE
/Long.MIN_VALUE
小?
使用Guava,它是那样简单
long c = LongMath.checkedAdd(a, b); // throws an ArithmeticException on overflow
是,我想认为,可读性很强确实如此。 (LongMath Javadoc here。)
为了公平起见,我会提到Apache Commons提供了ArithmeticUtils.addAndCheck(long, long)
。
如果你想知道他们是如何工作的,那么,答案是位两轮牛车为番石榴的一行:结果不会溢出,如果(a^b) < 0 | (a^(a + b)) >= 0
。这是基于技巧,两个数字的按位异或是非负当且仅当它们具有相同的符号。
所以(a^b) < 0
是真的如果a
和b
有不同的迹象,如果是这样的话,它永远不会溢出。或者,如果(a^(a + b)) >= 0
,则a + b
具有相同的符号为a
,所以也没溢出,变为负值。
(有关更多的技巧是这样,调查可爱的书Hacker's Delight)
Apache使用基础上的a
和b
符号更复杂的个案。
+1番石榴。即使比较(如我最初所建议的)可能有效(尽管我太困了,不能正确地考虑它),但愿意使用即用功能 – Bozho 2012-01-29 22:28:29
完全披露:我是“LongMath”的作者,其余的番石榴的common.math包...但@Bozho是正确的,它通常更好地依赖库代码而不是滚动自己的实现。(特别是,这个代码已经经过测试*非常详尽,所以你不必!) – 2012-01-29 22:32:33
非常酷。添加另一个完整的库可能会导致这样一个简单的情况(检测溢出在这种情况下是微不足道的),但如果你已经*使用番石榴... – 2012-01-29 22:34:32
一种选择是使用BigInteger
类做精确的计算,然后检查结果是否比有问题的值大于或更小。例如:
if (BigInteger.valueOf(a).add(BigInteger.valueOf(b)).compareTo(BigInteger.valueOf(Long.MAX_VALUE) > 1) {
/* Overflow occurred. */
} else {
/* No overflow occurred.
}
希望这有助于!
如果你打算继续使用全功能'BigInteger',你可以检查'myBigInt.bitLength()
@LouisWasserman正确,因为小于,否则它会被一个关闭。我不认为这两个选项中的任何一个都是可读的,并且其中一个答案只需要Long.MAX_VALUE,而不是Long.MIN_VALUE ... – 2012-01-29 22:42:24
一致认为这比它的可读性差。作为参考,虽然我会说BigInteger方法是检查* multiplication *溢出的最可读方法,如果您不愿意使用库。 – 2012-01-29 22:44:29
简约路线:
if(a/2+b/2+(a&b&1)>long.MAX_VALUE/2||a/2+b/2<long.MIN_VALUE/2)...
你只需要希望它不会优化(a+b)/2
我不相信这是正确的。取a = Long.MAX_VALUE和b = 1。然后,如果添加两个值,那么显然会发生溢出,但是如果将它们减半,a/2 = Long.MAX_VALUE/2和b/2 = 0,那么a/2 + b/2 <= Long.MAX_VALUE。 – templatetypedef 2012-01-29 22:38:24
@templatetypedef我修复了这个小技巧(增加了溢出) – 2012-01-29 23:20:04
这只是一个问题,如果它们具有相同的符号(和都!0
)因为否则你是安全的溢出。如果发生溢出,结果的符号将会翻转。所以:
long r = a + b;
if ((a < 0 && b < 0 && r >= 0) ||
(a > 0 && b > 0 && r <= 0)) {
// Overflow occurred
}
注册了,最简单,最易读和最好的方法。希望该课程不会采用更“优化”的数学方法。 – 2012-01-29 22:38:32
@owlstead,如果编译器足够聪明,它可以使用CPU“携带”标志,所以解决方案就够用了。当天返回的唯一算法是通过进位完成的。 – bestsss 2012-01-29 22:42:54
Upvoted为最适合家庭作业的解决方案。 – 2012-01-29 22:50:32
请参阅问题文本框右侧的**如何格式**框以及它上方的** [?] **链接(以及其下方的预览)正确设置问题的格式。 – 2012-01-29 22:18:56
在汇编,将有可能检查* *携带国旗? – 2012-01-29 22:22:08
我删除了[功课]标签,作为OP的评论跟帖,这是只有在那里偶然提及。 – 2012-01-29 23:01:01