Отрицание в 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
Причина, по которой используется дополнение до двух (вместо использования отдельного бита для знака), заключается в том, что оно делает вычитание и сложение тривиальными независимо от знаков.