首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么(18446744073709551615 == -1)是真的?

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

Stack Overflow用户
提问于 2016-11-15 10:58:38
回答 4查看 33.8K关注 0票数 27

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

代码语言:javascript
运行
复制
(string::npos == ULONG_MAX)

代码语言:javascript
运行
复制
(string::npos == -1)

都是真的。

所以我试了一下:

代码语言:javascript
运行
复制
(18446744073709551615 == -1)

这也是事实。

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

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2018-07-08 18:34:29

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,所有的位都是开着的。

代码语言:javascript
运行
复制
1111111111111111111111111111111111111111111111111111111111111111b

The -1

让我们来看看64位二进制文件中的+1

代码语言:javascript
运行
复制
0000000000000000000000000000000000000000000000000000000000000001b

为了使其在One's补体 (OCP)中为负值,我们对比特进行反转。

代码语言:javascript
运行
复制
1111111111111111111111111111111111111111111111111111111111111110b

计算机很少使用OCP,它们使用2的补码 (TCP)。要获得TCP,需要在OCP中添加一个。

代码语言:javascript
运行
复制
1111111111111111111111111111111111111111111111111111111111111110b (-1 in OCP)
+                                                              1b (1)
-----------------------------------------------------------------
1111111111111111111111111111111111111111111111111111111111111111b (-1 in TCP)

“但是,等等,”你问,如果在两个补充-1是,

代码语言:javascript
运行
复制
1111111111111111111111111111111111111111111111111111111111111111b

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

代码语言:javascript
运行
复制
1111111111111111111111111111111111111111111111111111111111111111b

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

更新

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

票数 34
EN

Stack Overflow用户

发布于 2016-11-15 11:05:16

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

票数 9
EN

Stack Overflow用户

发布于 2016-11-15 11:07:04

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

代码语言:javascript
运行
复制
static const size_type npos = -1;

其中std::string::size_type是一些无符号整数类型。因此,没有什么了不起的,std::string::npos等于-1。初始化器被转换为std::string::npos的类型。

至于这个方程式

代码语言:javascript
运行
复制
(string::npos == ULONG_MAX) is true,

然后,这意味着std::string::npos类型在使用的实现unsigned long中具有类型。此类型通常对应于size_t类型。

在这个方程式中

代码语言:javascript
运行
复制
(18446744073709551615 == -1)

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40608111

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档