Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is (uint64_t)-1 guaranteed to yield 0xffffffffffffffff?

Tags:

c++

c

standards

c11

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
like image 879
cmaster - reinstate monica Avatar asked Aug 18 '13 21:08

cmaster - reinstate monica


People also ask

What is the max value of uint64_t?

Remarks. The value of this constant is 18,446,744,073,709,551,615; that is, hexadecimal 0xFFFFFFFFFFFFFFFF.

Is uint64_t same as long long?

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.

What is u_int64_t?

The (uint64_t) is casting the value to an unsigned 64 bit integer. Equivalent to static_cast<uint64_t> in C++.


2 Answers

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.

like image 153
R.. GitHub STOP HELPING ICE Avatar answered Sep 20 '22 08:09

R.. GitHub STOP HELPING ICE


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.

like image 41
Pascal Cuoq Avatar answered Sep 21 '22 08:09

Pascal Cuoq