Отрицание в JavaScript

Может кто-нибудь объяснить, почему Javascript дает следующие результаты?

~3 = -4
~3.346346 = -4
~-3 = 2

2 ответа

Решение

~ является побитовым оператором отрицания[MDN].

3 в двоичном (с использованием 32-разрядного целого)

0000 0000 0000 0000 0000 0000 0000 0011 (3)

а также -3 в двоичном коде (с использованием дополнения до двух)

1111 1111 1111 1111 1111 1111 1111 1101 (-3)

~ Оператор меняет все 1с 0и все 0с 1, так ~3 будет

1111 1111 1111 1111 1111 1111 1111 1100 (~3 == -4)

который является двоичным для -4 (используя два дополнения).

Так же, ~-3 будет

0000 0000 0000 0000 0000 0000 0000 0010 (~-3 == 2)

который является двоичным для 2,

3.346346 будет приведен к целому числу при выполнении побитовых операций, поэтому он будет иметь тот же результат, что и 3 имел.


Подводить итоги:

  3 = 0000 0000 0000 0000 0000 0000 0011 = (int)3.346346
 ~3 = 1111 1111 1111 1111 1111 1111 1100 = -4
 -3 = 1111 1111 1111 1111 1111 1111 1101
~-3 = 0000 0000 0000 0000 0000 0000 0010 =  2

Это потому, что отрицательные числа хранятся как два дополнения:

minusB = ~B + 1;

В вашем случае, изменив формулу выше:

  • -3 хранится как ~3 + 1, Так, ~-3 эквивалентно -(-3) - 1 = 2,
  • ~3.346346 сначала округляется до 3, затем ~3 можно читать как -3 - 1 = -4

Причина, по которой используется дополнение до двух (вместо использования отдельного бита для знака), заключается в том, что оно делает вычитание и сложение тривиальными независимо от знаков.

Другие вопросы по тегам