6

I have a sum() function. I need to catch all overflow.

I searched website but didn't find a good way to do so.

So...any thoughts?

Potatoswatter
  • 134,909
  • 25
  • 265
  • 421
Anders Lind
  • 4,542
  • 8
  • 46
  • 59
  • depends on what you are summing. provide code – Karoly Horvath Sep 16 '11 at 23:05
  • Actually, the cross-referenced question is about _any default data type_, though it is certainly true that the primary example is about `float` rather than `int` in any of its various forms. The answers definitely cover some safe integer libraries though, and would therefore help the questioner. – Jonathan Leffler Sep 17 '11 at 00:02
  • See also: [Best way to detect integer overflow in C/C++](http://stackoverflow.com/questions/199333/best-way-to-detect-integer-overflow-in-c-c). – Jonathan Leffler Sep 17 '11 at 00:06

3 Answers3

9

As others have said, if the result is a different sign than both operands, two's complement signed overflow occurred.

The converse is also true. Two's complement signed overflow cannot occur unless the operands are the same sign (negative or non-negative) and the result is the opposite.

Still, personally, I prefer a more straightforward 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 signed and unsigned overflow/underflow, and it is much easier to see what is happening.

Moreover, integral signed overflow in C++ is not guaranteed to wrap around, since two's complement arithmetic is not required. Signed integer overflow can even crash, although it is unlikely. So in terms of the language, it's best to stop overflow before it occurs. C++03 §5/5:

If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined, unless such an expression is a constant expression (5.19), in which case the program is ill-formed. [Note: most existing implementations of C++ ignore integer overflows. …]

See also the Boost Numeric Conversion library, although I'm not sure it can do anything for this problem that std::numeric_limits can't.

Potatoswatter
  • 134,909
  • 25
  • 265
  • 421
-1

In order for an overflow to occur, both operands must be the same sign. If the sum of the operands is a different sign than the operands, then an overflow occurred.

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;
}

More concisely...

bool overflow( int a, int b )
{
    return ( ( a < 0 ) == ( b < 0 ) && ( a + b < 0 ) != ( a < 0 ) );
}
Michael Dorgan
  • 12,453
  • 3
  • 31
  • 61
Chris Vig
  • 8,552
  • 2
  • 27
  • 35
  • @Michael: The term integer underflow is often used to describe "overflowing" `INT_MIN`. Similarly `std::numeric_limits< float >::min()` is a very small value while `std::numeric_limits< int >::min()` is very large. – Potatoswatter Sep 17 '11 at 05:10
  • @Potatoswatter - and we both know that is incorrect. Though in this case, I was clearly incorrect :) – Michael Dorgan Sep 17 '11 at 16:35
  • 1
    This is undefined behaviour. – Ladislav Sep 10 '13 at 10:26
-2

__asm jno notoverflow;

__asm jo overflow.

Using asm is more convenient here.

    int main()
    {
        int x = 2147483647;
        x++;
        __asm jo overflowed;
        printf("Not Overflow\n");
        if(0)
        {
            overflowed:
            printf("Overflowed!\n");
        }
        return 0;
    }

Result: Overflowed

Chengxi Li
  • 454
  • 1
  • 3
  • 14
  • 1
    Could you elaborate on this? How would I use it in practice? – nibot Oct 17 '12 at 19:31
  • 3
    #1. not portable, (this example only overflows on x86 32bit). #2 should write the function completely in assembler, mixing c and asm without completely knowing the target compiler can be dangerous, as this example, the compiler could insert code after the math that could reset the overflow flag (may work for gcc but fail for intel/llvm) and may change depending on flags into the compiler (bounds checking). – Rahly Aug 25 '16 at 12:55