Почему ~ 5 === -6 в 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) говорится: "Побитовое NOT или дополнение - это унарная операция, которая выполняет логическое отрицание на каждом бите, образуя дополнение к данному двоичному значению. Биты, которые равны 0, становятся равными 1, а те, которые равны 1, становятся 0."

Теперь возьмите число 5 в двоичном формате: 0101

Если я наберу ~5 в моей консоли браузера, я получаю -6, двоичное представление которого 1110. Я ожидал, что отрицание превратит 0101 в 1010, что на самом деле 10 (или -2, если крайняя левая цифра считается знаком).

Все объяснения, которые я прочитал для оператора JavaScript ~, говорят, что он оценивает число - (x + 1), но это не объясняет мне логически, что этот оператор делает на "поразрядном" уровне.

В принципе, 0101 становится 1110.

Каковы промежуточные шаги, чтобы засвидетельствовать это преобразование? Я вижу, что ведущий бит становится перевернутым, тем самым меняя знак. Но это обо всем, что я могу собрать.

Ответ 1

Он действительно выполняет бит-му, НЕ, отрицательное число находится в два дополнения. Значением 1010 является -6.

Два дополнения в основном работают самым левым битом, обозначают отрицательное число и принимаются как отрицательное значение. Все остальные 1 бит добавляются к этому числу. Например:

1010 => (-8 +0 +2 +0) => -6
1111 => (-8 +4 +2 +1) => -1

Ответ 2

Почему побитовое "не 1" равный -2? - та же самая идея.
Ответ Цербруса в приведенной ссылке (BINARY R → L):
Есть 2 целых числа от 1 до -2: 0 и -1

1 в двоичном формате - 00000000000000000000000000000001
0 в двоичном формате - 00000000000000000000000000000000
-1 в двоичном формате - 11111111111111111111111111111111
-2 в двоичном формате - 11111111111111111111111111111110
( "двоичный", являющийся 2 дополнением, в случае побитового не ~)

Ответ 3

Вы очень приблизились к решению, осознав, что первый бит является знаком, однако остальные биты не используются "как есть". Фактически, при вычислении подписанные числа представлены двумя дополнениями.

Существуют подробные статьи о концепции Wikipedia и различных других веб-сайтах, но, короче говоря, когда первый бит равен 1 (с указанием отрицательное число), остальные биты составляют число, которое в основном показывает, сколько вы добавляете к минимальному числу (например, в 8-битовом целочисленном минимальном будет -256, который равен 11111111, поэтому инвертирование 5 (00000101) становится 11111010 или 250, поэтому вы можете получить десятичное значение, добавив 250 к -256, и вы получите -6). Это объяснение является упрощением для десятичных систем, но для полного понимания того, как это работает, вы должны действительно прочитать целую статью о двух дополнениях.

Ответ 4

Вас путают бит знака и место его размещения....

Увеличьте количество бит (например, очень короткий int из 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

So

11111010 -6

и

11111010 ~5

то же самое.

Это правда не только для JavaScript, но и для всего, что работает на компьютере, который основан на 2 системах с номерами дополнений, - не уверен, что JavaScript когда-либо выполнялся на любом другом: -)