c++ - 为什么 (18446744073709551615 == -1) 是真的?

标签 c++ equality unsigned signed integer-overflow

当我在处理 string::npos 时,我注意到了一些东西,但我在网上找不到任何解释。

(string::npos == ULONG_MAX)

(string::npos == -1)

是真的。

所以我尝试了这个:

(18446744073709551615 == -1)

这也是正确的。

这怎么可能?是因为二元对话吗?

最佳答案

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)。

我们看一下64位二进制的2^64 - 1,所有位都是on。

1111111111111111111111111111111111111111111111111111111111111111b

-1

让我们看看64位二进制的+1

0000000000000000000000000000000000000000000000000000000000000001b

为了使其在 One's Complement (OCP) 中为负,我们将位反转。

1111111111111111111111111111111111111111111111111111111111111110b

计算机很少使用 OCP,它们使用 Two's Complement (TCP)。要获取 TCP,请向 OCP 添加一个。

1111111111111111111111111111111111111111111111111111111111111110b (-1 in OCP)
+                                                              1b (1)
-----------------------------------------------------------------
1111111111111111111111111111111111111111111111111111111111111111b (-1 in TCP)

“但是,等等”你问,如果在二进制补码 -1 中,

1111111111111111111111111111111111111111111111111111111111111111b

并且,如果在二进制中 2^64 - 1

1111111111111111111111111111111111111111111111111111111111111111b

那么他们是平等的!而且,这就是你所看到的。您正在将有符号的 64 位整数与无符号的 64 位整数进行比较。在 C++ 中,这意味着将有符号值转换为无符号值,编译器会这样做。

更新

技术修正thanks to davmac in the comments ,从 -1 (即 signed 到相同大小的 unsigned 类型的转换实际上是在语言中指定的,而不是架构。总而言之,您可能会发现上面的答案对于理解支持双语恭维但缺乏确保您可以依赖的结果的规范的架构/语言很有用。

关于c++ - 为什么 (18446744073709551615 == -1) 是真的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40608111/

相关文章:

c++ - 为什么我在使用 Boost UUID 时会收到来自 Valgrind 的未初始化值警告?

c++ - Z3 - 浮点运算 API 函数 Z3_mk_fpa_to_ubv

java - 某些同等条件不起作用

objective-c - 如何在 NSLog() 中打印 unsigned char*

ruby - 如何在 ruby​​ 中声明 8 位无符号整数?

c++ - asio::io_service 和 thread_group 生命周期问题

c++ - 将函数/方法参数定义为指针并在没有引用的情况下传递

java - 如何在 Java 中比较字符串?

Python 在交互模式下不驻留字符串?

mysql - 为什么我不能将我的 INT 从无符号更改为有符号?可以签名 Zerofill 吗?