我有一个sum()
功能。
我需要抓住所有的溢出。
我搜索了网站,但没有找到一个好方法。
所以......有什么想法吗?
答案 0 :(得分:6)
正如其他人所说,如果结果与两个操作数的符号不同,则会发生二次补码签名溢出。
反过来也是如此。除非操作数是相同的符号(负数或非负数)且结果相反,否则不能发生二进制补码有符号溢出。
不过,就个人而言,我更喜欢更简单的方法:
int_type a = 12356, b = 98765432;
if ( b > 0 && a > std::numeric_limits< int_type >::max() - b )
throw std::range_error( "adding a and b would cause overflow" );
if ( b < 0 && a < std::numeric_limits< int_type >::min() - b )
throw std::range_error( "adding a and b would cause underflow" );
int_type c = a + b;
这将捕获有符号和无符号的溢出/下溢,并且更容易看到发生了什么。
此外,C ++中的积分有符号溢出不能保证包含,因为不需要二进制补码算法。有符号整数溢出甚至可能崩溃,尽管不太可能。所以就语言而言,最好在发生之前停止溢出。 C ++03§5/ 5:
如果在评估表达式期间,结果未在数学上定义或未在其类型的可表示值范围内,则行为未定义,除非此类表达式是常量表达式(5.19),在这种情况下,程序是不正确的。 [注意:大多数现有的C ++实现忽略整数溢出。 ...]
另请参阅Boost Numeric Conversion库,但我不确定它是否可以解决std::numeric_limits
无法解决的问题。
答案 1 :(得分:0)
__ asm jno notoverflow;
__ asm jo溢出。
在这里使用asm更方便。
int main()
{
int x = 2147483647;
x++;
__asm jo overflowed;
printf("Not Overflow\n");
if(0)
{
overflowed:
printf("Overflowed!\n");
}
return 0;
}
结果:溢出
答案 2 :(得分:-1)
为了发生溢出,两个操作数必须是相同的符号。如果操作数的总和与操作数的符号不同,则发生溢出。
bool overflow( int a, int b )
{
bool op_same_sign = ( a < 0 ) == ( b < 0 );
bool sum_diff_sign = ( a < 0 ) != ( a + b < 0 );
return op_same_sign && sum_diff_sign;
}
更简洁......
bool overflow( int a, int b )
{
return ( ( a < 0 ) == ( b < 0 ) && ( a + b < 0 ) != ( a < 0 ) );
}