I know, that it is well defined by the C standard that (unsigned)-1
must yield 2^n-1, i. e. an unsigned integer with all its bits set. The same goes for (uint64_t)-1ll
. However, I cannot find something in the C11 standard that specifies how (uint64_t)-1
is interpreted.
So, the question is: Is there any guarantee in the C standard, which of the following holds true?
(uint64_t)-1 == (uint64_t)(unsigned)-1 //0x00000000ffffffff
(uint64_t)-1 == (uint64_t)(int64_t)-1 //0xffffffffffffffff
Remarks. The value of this constant is 18,446,744,073,709,551,615; that is, hexadecimal 0xFFFFFFFFFFFFFFFF.
So unsigned long long is the same as uint64_t in the 32-bit compilation but not in 64-bit compilation? Yes. In 32-bit mode, most likely long is 32 bits and long long is 64 bits. In 64-bit mode, both are probably 64 bits.
The (uint64_t) is casting the value to an unsigned 64 bit integer. Equivalent to static_cast<uint64_t> in C++.
Yes. See C11 6.3.1.3 Signed and unsigned integers:
1 When a value with integer type is converted to another integer type other than _Bool, if the value can be represented by the new type, it is unchanged.
2 Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.60)
3 Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised.
60) The rules describe arithmetic on the mathematical value, not the value of a given type of expression.
Case 2 applies, so -1 is reduced modulo 0x10000000000000000 to yield 0xffffffffffffffff.
The expressions 1
and -1
have type int
. When converted to uint64_t
, the principle that 2n is added or subtracted until the value is in range applies, so the result is always 2n-1, in this case with n=64. Therefore, (uint64_t)-1
is always 264-1..
The expression (int64_t)-1
evaluates to -1, so the same reasoning applies to the expression (uint64_t)(int64_t)-1
, which too always evaluates to 264-1.
On the other hand, (unsigned)-1
is a positive value of type unsigned int
that may be 216-1, 232-1, 264-1 or various other values depending on the compilation platform. These values may not yield 264-1 when converted to uint64_t
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With