当我在 string::npos
上工作时,我注意到了一些东西,但我在网上找不到任何解释。
(string::npos == ULONG_MAX)
和
(string::npos == -1)
是真的。
所以我尝试了这个:
(18446744073709551615 == -1)
这也是正确的。
怎么可能?是因为二元对话吗?
原文由 Bahadır 发布,翻译遵循 CC BY-SA 4.0 许可协议
当我在 string::npos
上工作时,我注意到了一些东西,但我在网上找不到任何解释。
(string::npos == ULONG_MAX)
和
(string::npos == -1)
是真的。
所以我尝试了这个:
(18446744073709551615 == -1)
这也是正确的。
怎么可能?是因为二元对话吗?
原文由 Bahadır 发布,翻译遵循 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 许可协议
3 回答1.3k 阅读✓ 已解决
1 回答1.1k 阅读✓ 已解决
4 回答840 阅读
1 回答1.4k 阅读
1 回答916 阅读
1 回答950 阅读
1 回答716 阅读
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 位二进制中,所有位都打开。-1
让我们看一下 64 位二进制文件中的
+1
。为了使其在 One’s Complement (OCP) 中为负,我们将位反转。
计算机很少使用OCP,它们使用 Two’s Complement (TCP)。要获得 TCP,请向 OCP 添加一个。
“但是,等等”你问,如果在二进制补码中
-1
是,并且,如果在二进制中
2^64 - 1
是然后他们是平等的!而且,这就是你所看到的。您正在将有符号的 64 位整数与无符号的 64 位整数进行比较。在 C++ 中,这意味着将有符号值转换为无符号值,编译器会这样做。
更新
由于评论中的 davmac 进行 了技术更正,实际上在语言中指定了从
-1
即signed
到unsigned
类型的转换,而不是架构的功能。总而言之,您可能会发现上面的答案对于理解支持双相称的拱形/语言很有用,但缺乏确保您可以依赖的结果的规范。