Search code examples
c++integerprecision16-bitinteger-division

How does C++ integer division work for limit and negative values?


I am facing some strange results with integer division in C++. I am trying to calculate this: -2147483648 / -1.

What I get is 3 different results in 3 different scenarios:

int foo(int numerator, int denominator) {
    int res = numerator / denominator; // produces SIGFPE, Arithmetic exception interrupt

    cout << res << endl;
}

int main() {
    int res = -2147483648 / -1;
    cout << res << endl;               // prints -2147483648
    cout << -2147483648 / -1 << endl;  // prints 2147483648
    foo(-2147483648, -1);
    return 0;
}

Why does the integer division operation produces different results in different situations?


Solution

  • The literal -2147483648 / -1 is calculated by your compiler as 2147483648 in a data type that is wide enough to hold that value.

    When the literal is printed out directly, it prints the value correctly.

    When the literal is stored in res, it is cast to an int. An int appears to be 32 bits wide on your system. The value 2147483648 cannot be represented as a 32 bit signed integer, so the cast causes an overflow. On your system, this overflow results in the value -2147483648 (likely it's using two's complement).

    Finally, when trying to perform the division at runtime (in the foo function), the SIGFPE exception occurs due to the overflow (because the int datatype cannot represent the result).

    Note that all of these three options rely on platform dependent behavior :

    • the fact that the compiler doesn't generate any errors (or other issues) when the literal calculation overflows and just uses a data type large enough to hold the result
    • the fact that the int overflow when storing the literal generates that specific value (and no other issues)
    • the fact that the SIGFPE exception is thrown when overflowing at runtime