What happens when I assign a number larger than INT_MAX to an int?

Suppose I assign an eleven digits number to an int, what will happen? I played around with it a little bit and I know it's giving me some other numbers within the int range. How is this new number created?


Solution 1:

It is implementation-defined behaviour. This means that your compiler must provide documentation saying what happens in this scenario.

So, consult that documentation to get your answer.

A common way that implementations define it is to truncate the input integer to the number of bits of int (after reinterpreting unsigned as signed if necessary).

C++14 Standard references: [expr.ass]/3, [conv.integral]/3

Solution 2:

In C++20, this behavior will still be implementation-defined1 but the requirements are much stronger than before. This is a side-consequence of the requirement to use two's complement representation for signed integer types coming in C++20.

This kind of conversion is specified by [conv.integral]:

  1. A prvalue of an integer type can be converted to a prvalue of another integer type. [...]

  2. [...]

  3. Otherwise, the result is the unique value of the destination type that is congruent to the source integer modulo 2N, where N is the width of the destination type.

  4. [...]

This behaviour is the same as truncating the representation of the number to the width of the integer type you are assigning to, e.g.:

int32_t u = 0x6881736df7939752;

...will kept the 32 right-most bits, i.e., 0xf7939752, and "copy" these bits to u. In two's complement, this corresponds to -141322414.

1 This will still be implementation-defined because the size of int is implementation-defined. If you assign to, e.g., int32_t, then the behaviour is fully defined.


Prior to C++20, there were two different rules for unsigned and signed types:

  1. A prvalue of an integer type can be converted to a prvalue of another integer type. [...]
  2. If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source integer (modulo 2n where n is the number of bits used to represent the unsigned type). [...]
  3. If the destination type is signed, the value is unchanged if it can be represented in the destination type; otherwise, the value is implementation-defined.

Solution 3:

INT_MAX on a 32 bit system is 2,147,483,647 (231 − 1), UINT_MAX is 4,294,967,295 (232 − 1).

int thing = 21474836470;

What happens is implementation-defined, it's up to the compiler. Mine appears to truncate the higher bits. 21474836470 is 0x4fffffff6,

warning: implicit conversion from 'long' to 'int' changes
  value from 21474836470 to -10 [-Wconstant-conversion]
int thing = 21474836470;