Search code examples
cinteger-overflow

why sometimes I get overflow and sometimes not in C


I have this code, and the two calculations give me different results.
The first does an overflow and the second just stays with 2^31-1.

I can't figure out why.

int n4, n5;

n4 = pow(2, 31);
n4 = n4 + n4;
n5 = pow(2, 31) + pow(2, 31);

printf("\nn4: %d, n5: %d",n4,n5);
/* n4: -2, n5: 2147483647 */

Solution

  • The return value of pow is of type double.

    So, pow(2, 31) + pow(2, 31) is in the range a double can represent.

    The assignment n5 = (double) ... casts the double to an int. But since the value is not representable by an int, you get (2^31)-1 as result. Basically you clamp the double value to the max value of an int ((2^31)-1).

    The first case is an overflow, because the result of n4 + n4 is of type int. And the value exceeds the maximum.

    C Standard Draft N2176

    6.3 Conversions
    6.3.1.4 Real floating and integer

    1. When a finite value of real floating type is converted to an integer type other than _Bool, the fractional part is discarded (i.e., the value is truncated toward zero). If the value of the integral part cannot be represented by the integer type, the behavior is undefined.

    Yes, the conversion is UB. But to explain the result of the OP, i 'assumed' that the value has been clamped to the range of an int.