根据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将其参数转换为2个 32 整数值之一 在-2 31 至2 31 -1的范围内,包括端值。这个抽象操作的功能如下 如下:
- 设number是输入参数上调用ToNumber的结果。
- 如果数字是NaN,+ 0,-0,+∞或-∞,则返回+0。
- 让posInt为sign(number)* floor(abs(number))。
- 让int32bit为posint modulo 2 32 ;也就是说,Number的有限整数值k 类型为正数且小于2 32 的数量级为数学 posInt和k的差异在数学上是2 32
的整数倍。- 如果int32bit大于或等于2 31 ,则返回int32bit - 2 32 ,否则返回 return int32bit。
醇>
当参数为-1时,根据9.5, 在第1步 数字仍为-1, 跳过step2 在第3步 posInt将为-1 在第4步 int32bit将为1 在第5步中,它将返回1
哪一步错了?
答案 0 :(得分:15)
32位整数中的-1
1111 1111 1111 1111 1111 1111 1111 1111
所以~-1
将是
0000 0000 0000 0000 0000 0000 0000 0000
哪个是零。
32位整数中的1
0000 0000 0000 0000 0000 0000 0000 0001
所以~1
将是
1111 1111 1111 1111 1111 1111 1111 1110
哪个是-2
。
您应该阅读two's complement以了解二进制库中负整数的显示。
答案 1 :(得分:1)
你在哪里得到ToInt32(-1)
评估为1的想法?它的计算结果为-1,在32位,二进制补码二进制表示中,所有位都设置为1.当您应用~
运算符时,每个位都变为0,这表示0中的0- bit,二进制补码。
除了位0之外,1的表示都是位0。当位被反转时,除了位0之外,结果是所有位1。这恰好是-2的二进制补码表示。 (要看到这一点,只需从-1的二进制补码表示中减去1。)
答案 2 :(得分:0)
ToInt32(1)
将返回1
ToInt32(-1)
将返回-1
-1
通过设置全部32位表示为带符号的32位整数。所有位都是明确的,因此~-1
会产生0
1
表示为带符号的32位整数,除了底部位之外,所有位都清零。除了底部位之外,其所有位都设置为按位补码,底部位是值-2
的带符号32位整数表示。因此,~1
会产生-2