Bah*_*dır 12 c++ unsigned signed equality integer-overflow
当我在工作时,string::npos我注意到了一些东西,我在网上找不到任何解释.
(string::npos == ULONG_MAX)
Run Code Online (Sandbox Code Playgroud)
和
(string::npos == -1)
Run Code Online (Sandbox Code Playgroud)
是真的.
所以我尝试了这个:
(18446744073709551615 == -1)
Run Code Online (Sandbox Code Playgroud)
这也是事实.
怎么可能?是因为二元对话吗?
Eva*_*oll 10
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 - 164位二进制,所有位都打开。
1111111111111111111111111111111111111111111111111111111111111111b
Run Code Online (Sandbox Code Playgroud)
-1让我们看一下+164位二进制文件。
0000000000000000000000000000000000000000000000000000000000000001b
Run Code Online (Sandbox Code Playgroud)
为了使其在一个人的赞美(OCP)中为负,我们将这些位反转。
1111111111111111111111111111111111111111111111111111111111111110b
Run Code Online (Sandbox Code Playgroud)
计算机很少使用OCP,而是使用Two's Compliment(TCP)。要获得TCP,请将一个添加到OCP。
1111111111111111111111111111111111111111111111111111111111111110b (-1 in OCP)
+ 1b (1)
-----------------------------------------------------------------
1111111111111111111111111111111111111111111111111111111111111111b (-1 in TCP)
Run Code Online (Sandbox Code Playgroud)
您问“但是,等等”,如果在Twos Compliment -1中,
1111111111111111111111111111111111111111111111111111111111111111b
Run Code Online (Sandbox Code Playgroud)
并且,如果以二进制形式2^64 - 1是
1111111111111111111111111111111111111111111111111111111111111111b
Run Code Online (Sandbox Code Playgroud)
那么他们是平等的!而且,这就是您所看到的。您正在将有符号的64位整数与无符号的64位整数进行比较。在C ++中,这意味着将带符号的值转换为无符号,编译器会这样做。
由于注释中的davmac,为了进行技术更正,实际上是在语言中指定了从-1该大小到相同大小signed的unsigned类型的转换,而不是体系结构的功能。综上所述,您可能会发现上面的答案对于理解支持两个人称赞但缺乏确保您可以依靠的结果的规范的语言很有帮助。
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(但能够保持相关系统上最大可能数组的大小).