为什么 ~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 是否曾经 运行 做过其他事情:-)