Почему побитовая операция (~0);
печатает -1? В двоичном, а не 0 должно быть 1. Зачем ?Побитовый оператор
ответ
Вы на самом деле довольно близко.
В двоичном, а не 0 должно быть 1
Да, это совершенно правильно, когда мы говорим об один бит.
HOWEVER, int
, значение которого равно 0, фактически составляет 32 бита всех нулей! ~
инвертирует все 32 нуля до 32 единиц.
System.out.println(Integer.toBinaryString(~0));
// prints "11111111111111111111111111111111"
Это дополнение представление этих двух по -1
.
Аналогично:
System.out.println(Integer.toBinaryString(~1));
// prints "11111111111111111111111111111110"
То есть, для 32-битных беззнаковых int
в дополнительном представлении, ~1 == -2
.
Дальнейшее чтение:
- Two's complement
- Это система, которая используется Java (среди прочих) для представления подписано числовое значение в битах
- JLS 15.15.5 Bitwise complement operator
~
- «отмечают, что во всех случаях,
~x
равно(-x)-1
»
- «отмечают, что во всех случаях,
Потому что ~
не является бинарной инверсией, это побитовая инверсия. Бинарная инверсия будет !
и может (в Java) применяться только к логическим значениям.
В стандартном двоичном кодировании 0 все 0s, ~
побитовое NOT. Все 1s (чаще всего) -1 для целочисленных типов со знаком. Таким образом, для знакового типа Byte:
0xFF = -1 // 1111 1111
0xFE = -2 // 1111 1110
...
0xF0 = -128 // 1000 0000
0x7F = 127 // 0111 1111
0x7E = 126 // 0111 1110
...
0x01 = 1 // 0000 0001
0x00 = 0 // 0000 0000
Это двоичная инверсия, а во втором дополнении -1 является двоичной инверсией 0.
То, что вы на самом деле сказать, ~ 0x00000000 и что приводит к 0xFFFFFFFF. Для (подписанного) int в java это означает -1.
~
является побитовым оператором.
~0 = 1 which is -1 in 2's complement form
http://en.wikipedia.org/wiki/Two's_complement
Некоторые номера в форме дополнения до двух и их побитовое не ~
(чуть ниже них):
0 1 1 1 1 1 1 1 = 127
1 0 0 0 0 0 0 0 = -1280 1 1 1 1 1 1 0 = 126
1 0 0 0 0 0 0 1 = -1271 1 1 1 1 1 1 1 = -1
0 0 0 0 0 0 0 0 = 01 1 1 1 1 1 1 0 = -2
0 0 0 0 0 0 0 1 = 11 0 0 0 0 0 0 1 = -127
0 1 1 1 1 1 1 0 = 1261 0 0 0 0 0 0 0 = -128
0 1 1 1 1 1 1 1 = 127
+1 для примера. Программисты, которые любят головоломки, могут узнать, как и как работает, и как два дополнения работают только от тщательного изучения вашего примера! –
0 здесь немного. Это байт (по крайней мере, или более) - 00000000. Используя побитовое или мы будем иметь 11111111. Это -1, как целое число со ...
Для 32-битового целого числа
~00000000000000000000000000000000=11111111111111111111111111111111
(что - 1)
Вы можете представить себе первый бит в подписанном числе - (2 x -1), где x - количество бит.
Итак, дано 8-разрядное число, значение каждого бита (в порядке слева направо) находится:
-128 64 32 16 8 4 2 1
Теперь, в двоичном, 0, очевидно, все 0s:
-128 64 32 16 8 4 2 1
0 0 0 0 0 0 0 0 0 = 0
И когда вы побитовое не ~
каждый из этих 0s становится 1:
-128 64 32 16 8 4 2 1
~0 1 1 1 1 1 1 1 1
= -128+64+32+16+8+4+2+1 == -1
Это также полезно я n понимание переполнения:
-128 64 32 16 8 4 2 1
126 0 1 1 1 1 1 1 0 = 126
+1 0 1 1 1 1 1 1 1 = 127
+1 1 0 0 0 0 0 0 0 = -128 overflow!
Более ясные примеры, спасибо! –
Я думаю, что реальная причина заключается в том, что ~ является дополнением до двух.
Javascript обозначает символ тильды ~, для дополнения двух, хотя в большинстве языков программирования тильда представляет собой бит для переключения своего дополнения.
Если вы хотите перевернуть один бит, используйте 'x^1'. – kennytm
Это не оператор «не». Это оператор «дополнения». – EJP
@EJP: Оператор дополнения *** ***. – kennytm