As others said, if the result is different from both operands, two overflows occurred with addition.
The converse is also true. An overflow with two additions cannot occur if the operands are not the same sign (negative or non-negative), and the result is the opposite.
I personally prefer a simpler approach:
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;
This will catch both signature overflow / underflow and unsigned, and itβs much easier to see what happens.
In addition, integral signed overflow in C ++ is not guaranteed by wrapping, since arithmetic with two additions is not required. A signed integer overflow can even crash, although this is unlikely. Thus, from the point of view of the language, it is better to stop the overflow before it occurs. C ++ 03 Β§5 / 5:
If during the evaluation of an expression the result is not determined mathematically or not in the range of representable values ββfor its type, the behavior is undefined if such an expression is not a constant expression (5.19), in which if the program is poorly formed. [Note: most existing C ++ implementations ignore whole overflows ....]
See also the Boost Numeric Conversion library, although I'm not sure that it can do anything for this problem, that std::numeric_limits etc.
source share