Почему битовая операция (~0);
печать-1? В двоичном файле, не 0 должен быть 1. почему?
На самом деле вы довольно близко.
В двоичном формате не 0 должен быть 1
Да, это абсолютно правильно, когда мы говорим об одном бите.
ОДНАКО, 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
.
Дополнительная литература:
~
~ x
равно (- x) -1
"Для 32-битного целого числа со знаком
~ 00000000000000000000000000000000 = 11111111111111111111111111111111
(что равно -1)
Фактически вы говорите ~ 0x00000000, что приводит к 0xFFFFFFFF. Для (подписанного) int в java это означает -1.
Можно представить первый бит в знаковом числе как -(2x -1), где x - количество битов.
Таким образом, если взять 8-битное число, значение каждого бита (в порядке слева направо) будет:
-128 64 32 16 8 4 2 1
Теперь, в двоичном исчислении, 0 - это, очевидно, все 0:
-128 64 32 16 8 4 2 1
0 0 0 0 0 0 0 0 0 = 0
И когда вы делаете побитовое не ~
, каждый из этих 0 становится 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
Это также полезно для понимания переполнения:
-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!
Это двоичная инверсия, а во втором дополнении -1 - двоичная инверсия 0.
~
- побитовый оператор.
~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
0 здесь не бита. Это байт (по крайней мере; или больше) - 00000000. Используя побитовое, мы получим 11111111. Это -1 как целое число со знаком ...
Поскольку ~
не является двоичной инверсией, это побитовая инверсия. Двоичная инверсия будет !
и может (в Java) применяться только к логическим значениям.
В стандартном двоичном кодировании 0 - это все нули, ~
- побитовое НЕ. Все единицы равны (чаще всего) -1 для целочисленных типов со знаком. Итак, для байтового типа со знаком:
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