添加/减去两个long类型的数字。有没有办法弄清楚这个操作是否会设置理论进位?
答案 0 :(得分:3)
这应该做:
/**
* Add two long's with overflow detection (r = s + d)
*/
public static long add(final long s, final long d){
final long r = s + d;
if (((s & d & ~r) | (~s & ~d & r)) < 0)
throw new RuntimeException("long overflow add(" + s + ", " + d + ")");
return r;
}
此前已经提到过这个问题:How does Java handle integer underflows and overflows and how would you check for it?(此处也有减法描述)
编辑:由于不清楚OP是否意味着无符号加法,因此也不难发现。如果重新考虑问题为“如果我们有两个(无符号)64位值并且会添加它们,那么将在结果中设置位64(假设位从0 = LSB到63 =原始操作数中的MSB编号)”< / p>
一点点逻辑思维得出的结论是,如果满足下列条件之一,则会设置第64位:
相当容易检查:
long operand1 = ...
long operand2 = ...
long bitMask = Long.MAX_VALUE; // bits 0-62 set, bit 63 clear
int conditions = 0;
if (operand1 < 0)
++conditions;
if (operand2 < 0)
++conditions;
if (((operand1 & bitMask) + (operand2 & bitMask)) < 0)
++conditions;
if (conditions > 1)
System.out.println("carry would be set!");
我没有花时间思考如何优化,我相信有更简洁的解决方案。
对于无符号减法,它非常简单:如果b大于a,则在(a-b)中进行借位。可以使用无符号比较来检查,可以用java表示:
long flipSignBit = Long.MIN_VALUE; // only bit 63 set, others clear
if ((a ^ flipSignBit) < (b ^ flipSignBit))
System.out.println("borrow occurs");
答案 1 :(得分:1)
来自Java语言规范(Java SE 8)整数运算符不以任何方式表示溢出或下溢。所以你必须自己测试一下:
只要您在数字之间的每次操作中进行测试,就可以了。