为啥 ~-1 等于 0 而 ~1 等于 -2?
Posted
技术标签:
【中文标题】为啥 ~-1 等于 0 而 ~1 等于 -2?【英文标题】:Why does ~-1 equal 0 and ~1 equal -2?为什么 ~-1 等于 0 而 ~1 等于 -2? 【发布时间】:2013-08-17 22:35:58 【问题描述】:根据 ECMAScript 5.1 标准的 11.4.8 小节:
产生式 UnaryExpression : ~ UnaryExpression 评估如下:
让
expr
成为评估UnaryExpression的结果。 让oldValue
成为ToInt32(GetValue(expr))
。 将按位补码的结果返回到oldValue
。结果是一个带符号的 32 位整数。
~
运算符将调用内部方法ToInt32
。据我了解,ToInt32(1)
和 ToInt32(-1)
将返回相同的值 1 ,但为什么 ~-1
等于 0 和 ~1
等于 -2?
现在我的问题是为什么ToInt32(-1)
等于-1?
ECMAScript 5.1 标准的9.5 小节:
抽象操作 ToInt32 将其参数转换为 232 个整数值之一 在 -231 到 231-1 的范围内,包括端点。这个抽象操作的作用是 如下:
令 number 为对输入参数调用 ToNumber 的结果。 如果数字是 NaN、+0、-0、+∞ 或 -∞,则返回 +0。 让 posInt 为 sign(number) * floor(abs(number))。 令 int32bit 为 posInt 模 232;即 Number 的有限整数值 k 输入正号且幅度小于 232 使得数学 posInt 和 k 的差在数学上是 232 的整数倍。 如果int32bit大于等于231,返回int32bit-232,否则 返回 int32bit。
当参数为-1时,根据9.5, 在步骤 1 数字仍然是-1, 跳过步骤 2 在步骤 3 posInt 将为 -1 在第 4 步 int32bit 将为 1 在第 5 步中,它将返回 1
哪一步错了?
【问题讨论】:
ToIn32(-1) 应该根据ecma-international.org/ecma-262/5.1/#sec-9.5产生-1 您的理解是错误的,在您之前的问题中已得到纠正...(更具体地说,在我的回答中) what is the result of 'x modulo y'?的可能重复 在查找有关波浪号的信息时发现这很有帮助。 javascriptturnsmeon.com/the-tilde-operator-in-javascript。基本上~x === -(x + 1)
【参考方案1】:
-1
32 位整数
1111 1111 1111 1111 1111 1111 1111 1111
所以~-1
将是
0000 0000 0000 0000 0000 0000 0000 0000
这是零。
1
32 位整数
0000 0000 0000 0000 0000 0000 0000 0001
所以~1
将是
1111 1111 1111 1111 1111 1111 1111 1110
这是-2
。
您应该阅读two's complement 以了解以二进制为基础的负整数的显示。
【讨论】:
感谢您显示我的错误,我只是想念输入这个值。它是固定的。【参考方案2】:您从哪里得知ToInt32(-1)
的计算结果为 1?它的计算结果为 -1,在 32 位二进制补码表示中,所有位都设置为 1。当您应用 ~
运算符时,每个位都变为 0,这是 0 在 32 位中的表示,二进制补码。
1 的表示是除了位 0 之外的所有位 0。当位反转时,结果是除了位 0 之外的所有位 1。这恰好是 -2 的二进制补码表示。 (要看到这一点,只需从 -1 的二进制补码表示中减去 1。)
【讨论】:
【参考方案3】:ToInt32(1)
将返回 1
ToInt32(-1)
将返回 -1
-1
通过设置所有 32 位表示为带符号的 32 位整数。其按位补码全部清除,因此~-1
产生0
1
表示为一个带符号的 32 位整数,除底部位外,所有位都被清除。它的按位补码设置了除底部位之外的所有位,底部位是值-2
的有符号32 位整数表示。因此,~1
产生 -2
【讨论】:
以上是关于为啥 ~-1 等于 0 而 ~1 等于 -2?的主要内容,如果未能解决你的问题,请参考以下文章
为啥分割模型库的预测输出(值)是(0到1)而不是(0或1)?
在servicestack中使用protobuf,为啥order只能从1而不是0开始?
为啥 Stack 使用基于 1 的索引而不是 Java 中的 Array 中的基于 0 的索引?