为什么 ~5 === -6 在 JavaScript 中?
Why is ~5 === -6 in JavaScript?
注意:以下所有二进制表示都应从右到左阅读。我不确定为什么我会这样想它们,但我实际上并不知道人们也从左到右表示二进制。令人困惑!
在 MDN 关于 JavaScript 的按位运算符 (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_NOT) 的文章中,它说 ~
运算符是按位 NOT
运算符。
维基百科 (https://en.wikipedia.org/wiki/Bitwise_operation#NOT) 上写着 "The bitwise NOT, or complement, is a unary operation that performs logical negation on each bit, forming the ones' complement of the given binary value. Bits that are 0 become 1, and those that are 1 become 0."
现在,取二进制数 5:0101
如果我在浏览器控制台中键入 ~5
,我会得到 -6
,其二进制表示形式为 1110
。我希望否定将 0101
变成 1010
,这实际上是 10(如果最左边的数字被当作符号,则为 -2)。
我读到的关于 JavaScript 的 ~
运算符的所有解释都说它将数字计算为 -(x+1),但这并没有从逻辑上向我解释那是什么操作员的工作水平达到 "bitwise"。
基本上,0101
变成了 1110
。
见证这种转变的中间步骤是什么?我看到前导位被翻转,从而改变了符号。但我能收集到的就这些了。
同理
Cerebrus 在上面的回答 link (BINARY R -> L):
1和-2之间有2个整数:0和-1
1 在二进制中是 00000000000000000000000000000001
0 在二进制中是 00000000000000000000000000000000
-1 在二进制中是 1111111111111111111111111111111
-2 二进制为 1111111111111111111111111111110
("binary" 是 2 的补码,在按位非 ~ 的情况下)
它确实执行了按位非运算,负数在two's complement中。所以值 1010
是 -6
.
补码的基本原理是最左边的位表示负数,取负值。所有其他 1 位都添加到该数字。例如:
1010 => (-8 +0 +2 +0) => -6
1111 => (-8 +4 +2 +1) => -1
通过意识到第一位是符号,您已经非常接近解决方案,但是,没有使用其余位 'as is'。事实上,在计算中,有符号数是用二进制补码表示的。
在Wikipedia和其他各种网站上都有关于这个概念的详细文章,但简而言之,当第一个位为1(表示负数)时,其余位组成一个数基本上显示了您添加到最小数字的多少(例如,在 8 位整数中,最小数字为 -256,即 11111111
,因此反转 5 (00000101
) 变为 11111010
或 250,所以你可以通过将 250 添加到 -256 得到小数点,你得到 -6)。这个解释是对十进制系统的简化,但要完全理解它是如何工作的,你应该真正阅读整篇关于二进制补码的文章。
您对符号位及其放置位置感到困惑....
扩展位数(例如,一个非常短的 8 位整数)并查看
00000110 6
位反转~
00000101 5
11111010 ~5 (bitwise inversion of 5)
从零开始倒数
00000000 0
11111111 -1
11111110 -2
11111101 -3
11111100 -4
11111011 -5
11111010 -6
所以
11111010 -6
和
11111010 ~5
也是一样。
这是正确的 不仅对于 JavaScript,而且对于基于 2 补数系统的计算机上 运行 的任何东西 --不确定 JavaScript 是否曾经 运行 做过其他事情:-)
注意:以下所有二进制表示都应从右到左阅读。我不确定为什么我会这样想它们,但我实际上并不知道人们也从左到右表示二进制。令人困惑!
在 MDN 关于 JavaScript 的按位运算符 (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_NOT) 的文章中,它说 ~
运算符是按位 NOT
运算符。
维基百科 (https://en.wikipedia.org/wiki/Bitwise_operation#NOT) 上写着 "The bitwise NOT, or complement, is a unary operation that performs logical negation on each bit, forming the ones' complement of the given binary value. Bits that are 0 become 1, and those that are 1 become 0."
现在,取二进制数 5:0101
如果我在浏览器控制台中键入 ~5
,我会得到 -6
,其二进制表示形式为 1110
。我希望否定将 0101
变成 1010
,这实际上是 10(如果最左边的数字被当作符号,则为 -2)。
我读到的关于 JavaScript 的 ~
运算符的所有解释都说它将数字计算为 -(x+1),但这并没有从逻辑上向我解释那是什么操作员的工作水平达到 "bitwise"。
基本上,0101
变成了 1110
。
见证这种转变的中间步骤是什么?我看到前导位被翻转,从而改变了符号。但我能收集到的就这些了。
Cerebrus 在上面的回答 link (BINARY R -> L):
1和-2之间有2个整数:0和-1
1 在二进制中是 00000000000000000000000000000001
0 在二进制中是 00000000000000000000000000000000
-1 在二进制中是 1111111111111111111111111111111
-2 二进制为 1111111111111111111111111111110
("binary" 是 2 的补码,在按位非 ~ 的情况下)
它确实执行了按位非运算,负数在two's complement中。所以值 1010
是 -6
.
补码的基本原理是最左边的位表示负数,取负值。所有其他 1 位都添加到该数字。例如:
1010 => (-8 +0 +2 +0) => -6
1111 => (-8 +4 +2 +1) => -1
通过意识到第一位是符号,您已经非常接近解决方案,但是,没有使用其余位 'as is'。事实上,在计算中,有符号数是用二进制补码表示的。
在Wikipedia和其他各种网站上都有关于这个概念的详细文章,但简而言之,当第一个位为1(表示负数)时,其余位组成一个数基本上显示了您添加到最小数字的多少(例如,在 8 位整数中,最小数字为 -256,即 11111111
,因此反转 5 (00000101
) 变为 11111010
或 250,所以你可以通过将 250 添加到 -256 得到小数点,你得到 -6)。这个解释是对十进制系统的简化,但要完全理解它是如何工作的,你应该真正阅读整篇关于二进制补码的文章。
您对符号位及其放置位置感到困惑....
扩展位数(例如,一个非常短的 8 位整数)并查看
00000110 6
位反转~
00000101 5
11111010 ~5 (bitwise inversion of 5)
从零开始倒数
00000000 0
11111111 -1
11111110 -2
11111101 -3
11111100 -4
11111011 -5
11111010 -6
所以
11111010 -6
和
11111010 ~5
也是一样。
这是正确的 不仅对于 JavaScript,而且对于基于 2 补数系统的计算机上 运行 的任何东西 --不确定 JavaScript 是否曾经 运行 做过其他事情:-)