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

新手上路,请多包涵

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

 (string::npos == ULONG_MAX)

(string::npos == -1)

是真的。

所以我尝试了这个:

 (18446744073709551615 == -1)

这也是正确的。

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

原文由 Bahadır 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 2.4k
2 个回答

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 ,它有两个可能的值: 01 (2)。

让我们看看 2^64 - 1 在 64 位二进制中,所有位都打开。

 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++ 中,这意味着将有符号值转换为无符号值,编译器会这样做。

更新

由于评论中的 davmac 进行 了技术更正,实际上在语言中指定了从 -1signedunsigned 类型的转换,而不是架构的功能。总而言之,您可能会发现上面的答案对于理解支持双相称的拱形/语言很有用,但缺乏确保您可以依赖的结果的规范。

原文由 Evan Carroll 发布,翻译遵循 CC BY-SA 4.0 许可协议

string::npos 被定义为 constexpr static std::string::size_type string::npos = -1; (或者如果它在类定义中定义为 constexpr static size_type npos = -1; 但这真的无关紧要)。

将负数转换为无符号类型( std::string::size_type 基本上是 std::size_t ,它是无符号的)的环绕完全由标准定义。 -1 包装为无符号类型的最大可表示值,在您的情况下为 18446744073709551615 。请注意,确切的值是实现定义的,因为 std::size_t 的大小是实现定义的(但能够保持相关系统上最大可能数组的大小)。

原文由 rubenvb 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题