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

问题描述 投票:12回答:4

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

(string::npos == ULONG_MAX)

(string::npos == -1)

是真的。

所以我尝试了这个:

(18446744073709551615 == -1)

这也是事实。

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

c++ equality unsigned signed integer-overflow
4个回答
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,它有两个可能的值:01(2)。

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

1111111111111111111111111111111111111111111111111111111111111111b

The -1

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

0000000000000000000000000000000000000000000000000000000000000001b

为了使其在One的补语(OCP)中为负,我们将位反转。

1111111111111111111111111111111111111111111111111111111111111110b

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

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

“但是,等等”你问,如果在二人的补充中,qazxsw poi是,

-1

并且,如果在二进制1111111111111111111111111111111111111111111111111111111111111111b

2^64 - 1

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

更新

对于技术修正1111111111111111111111111111111111111111111111111111111111111111b ,从thanks to davmac in the comments -1到相同大小的signed类型的转换实际上在语言中指定,而不是该体系结构的功能。总而言之,您可能会发现上面的答案对于理解支持两个赞美但没有确保您可以依赖的结果的规范的语言/语言非常有用。


8
投票

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的大小是实现定义的(但能够保持相关系统上最大可能数组的大小)。


1
投票

根据C ++标准(文档号:N3337或文档号:N4296),std::size_t定义如下

std::string::npos

其中std :: string :: size_type是一些无符号整数类型。所以std :: string :: npos等于-1并不是什么好事。初始化程序转换为static const size_type npos = -1; 的tyhpe。

至于这个等式

std::string::npos

那么它意味着类型(string::npos == ULONG_MAX) is true, 在使用的实现std::string::npos中有类型。此类型通常对应于unsigned long类型。

在这个等式中

size_t

左侧文字有一些无符号整数类型,适合存储这么大的文字。因此,通过传播符号位,右操作数也被转换为这种无符号类型。由于左操作数表示该类型的最大值,因此它们是相等的。


0
投票

这完全是关于有符号溢出以及负数存储为2s补码的事实。意味着要获得负数的绝对值,您可以反转所有位并添加一个。在进行8位比较时的含义255和-1具有相同的二进制值11111111.这同样适用于更大的整数

(18446744073709551615 == -1)

© www.soinside.com 2019 - 2024. All rights reserved.