Search code examples
c++signedinteger-overflowlong-long

C++ Why does LLONG_MIN == -LLONG_MIN


In C++ if I do this:

__int64 var = LLONG_MIN;
__int64 var2 = -var;
cout << "var: "<< var << endl;
cout << "var2: "<< var2 << endl;

The output I get is:

var: -9223372036854775808
var2: -9223372036854775808

What is the part of the standard that covers this? I assume it's signed integer overflow. This was compiled using g++ (GCC) 4.7.2.

I have a subtract function and I'm writing an add function and I thought I could just do this: add( someobj &obj, long long num ) { subtract( obj, -num ); }. I think that would work if it wasn't for LLONG_MIN.


Solution

  • It is indeed integer overflow, and an artefact of two's complement.

    On your implementation, LLONG_MIN is -9223372036854775808 which is 0x8000000000000000 in hexadecimal (I will be using this hexadecimal notation because it's easier to see what happens to the bits).

    When you compute -LLONG_MIN on a system that uses two's complement, under the hood you first make a bitwise-not (yielding 0x7FFFFFFFFFFFFFFF == LLONG_MAX) then add 1 which overflows the signed integer and gives back 0x8000000000000000 == LLONG_MIN.

    Note that signed integer overflow is Undefined Behaviour, so there is no guarantee that it will behave consistently on every C++ implementation.