如何在C++中捕获整数溢出?

And*_*ind 4 c++ math overflow

我有一个sum()功能.我需要抓住所有溢出.

我搜索了网站,但没有找到一个好方法.

那么......有什么想法吗?

Pot*_*ter 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;
Run Code Online (Sandbox Code Playgroud)

这将捕获有符号和无符号溢出/下溢,并且更容易看到发生了什么.

此外,C++中的积分有符号溢出不能保证包含,因为不需要二进制补码算法.有符号整数溢出甚至可能崩溃,尽管不太可能.因此,就语言而言,最好在溢出发生之前停止溢出.C++03§5/ 5:

如果在评估表达式期间,结果未在数学上定义或未在其类型的可表示值范围内,则行为未定义,除非此类表达式是常量表达式(5.19),在这种情况下程序生病-formed.[注意:大多数现有的C++实现忽略整数溢出....]

另请参阅Boost数字转换库,虽然我不确定它可以为这个问题做任何事情std::numeric_limits.


Chr*_*Vig -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;
}
Run Code Online (Sandbox Code Playgroud)

更简洁一点...

bool overflow( int a, int b )
{
    return ( ( a < 0 ) == ( b < 0 ) && ( a + b < 0 ) != ( a < 0 ) );
}
Run Code Online (Sandbox Code Playgroud)