2010-03-25 4 views
34

Почему побитовая операция (~0); печатает -1? В двоичном, а не 0 должно быть 1. Зачем ?Побитовый оператор

+7

Если вы хотите перевернуть один бит, используйте 'x^1'. – kennytm

+1

Это не оператор «не». Это оператор «дополнения». – EJP

+1

@EJP: Оператор дополнения *** ***. – kennytm

ответ

64

Вы на самом деле довольно близко.

В двоичном, а не 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»
3

Потому что ~ не является бинарной инверсией, это побитовая инверсия. Бинарная инверсия будет ! и может (в Java) применяться только к логическим значениям.

1

В стандартном двоичном кодировании 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 
0

Это двоичная инверсия, а во втором дополнении -1 является двоичной инверсией 0.

13

То, что вы на самом деле сказать, ~ 0x00000000 и что приводит к 0xFFFFFFFF. Для (подписанного) int в java это означает -1.

7

~ является побитовым оператором.

~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 = -128

0 1 1 1 1 1 1 0 = 126
1 0 0 0 0 0 0 1 = -127

1 1 1 1 1 1 1 1 = -1
0 0 0 0 0 0 0 0 = 0

1 1 1 1 1 1 1 0 = -2
0 0 0 0 0 0 0 1 = 1

1 0 0 0 0 0 0 1 = -127
0 1 1 1 1 1 1 0 = 126

1 0 0 0 0 0 0 0 = -128
0 1 1 1 1 1 1 1 = 127

+0

+1 для примера. Программисты, которые любят головоломки, могут узнать, как и как работает, и как два дополнения работают только от тщательного изучения вашего примера! –

0

0 здесь немного. Это байт (по крайней мере, или более) - 00000000. Используя побитовое или мы будем иметь 11111111. Это -1, как целое число со ...

0

Для 32-битового целого числа

~00000000000000000000000000000000=11111111111111111111111111111111 (что - 1)

9

Вы можете представить себе первый бит в подписанном числе - (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! 
+0

Более ясные примеры, спасибо! –

0

Я думаю, что реальная причина заключается в том, что ~ является дополнением до двух.

Javascript обозначает символ тильды ~, для дополнения двух, хотя в большинстве языков программирования тильда представляет собой бит для переключения своего дополнения.