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]:
A prvalue of an integer type can be converted to a prvalue of another integer type. [...]
[...]
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.
[...]
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:
- A prvalue of an integer type can be converted to a prvalue of another integer type. [...]
- 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). [...]
- 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;