18,446,744,073,709,551,615
提到的这个数字,18,446,744,073,709,551,615,实际上是2^64 − 1。这里重要的是2^64-1本质上是基于0的2^64。无符号整数的第一位是0,而不是1。所以如果最大值是1,它有两个可能的值:0,或者1(2)。
让我们看看2^64 - 1在64位二进制中,所有位都打开了。
1111111111111111111111111111111111111111111111111111111111111111b
-1
让我们看一下+1 的 64 位二进制文件。
0000000000000000000000000000000000000000000000000000000000000001b
为了使其在 One's Complement (OCP) 中为负,我们将位反转。
1111111111111111111111111111111111111111111111111111111111111110b
计算机很少使用 OCP,它们使用 Two's Complement (TCP)。要获取 TCP,请向 OCP 添加一个。
1111111111111111111111111111111111111111111111111111111111111110b (-1 in OCP)
+ 1b (1)
-----------------------------------------------------------------
1111111111111111111111111111111111111111111111111111111111111111b (-1 in TCP)
“但是,等等”你问,如果在 Twos Complement -1 中,
1111111111111111111111111111111111111111111111111111111111111111b
并且,如果在二进制中 2^64 - 1 是
1111111111111111111111111111111111111111111111111111111111111111b
那么他们是平等的!而且,这就是你所看到的。您正在将有符号的 64 位整数与无符号的 64 位整数进行比较。在 C++ 中,这意味着将有符号值转换为无符号值,编译器会这样做。
更新
对于thanks to davmac in the comments 的技术更正,从-1(即signed)到相同大小的unsigned 类型的转换实际上是在语言中指定的,而不是架构的功能。总而言之,您可能会发现上面的答案对于理解支持双语恭维但缺乏规范以确保您可以依赖的结果的架构/语言很有用。