2013-07-05 17 views
12

Używam operacji ~ do manipulacji bitami i zastanawiam się, w jaki sposób Java oblicza liczbę ujemną?W jaki sposób Java oblicza liczby ujemne?

sprawdziłem dokumentację Java:

„jednoargumentowych operatory bitowe dopełnienie«~»odwraca wzór bitowy i może być stosowany do każdego z integralnych typów, dzięki czemu każdy«0»a«1» a każdy "1" to "0", np. bajt zawiera 8 bitów, zastosowanie tego operatora do wartości, której wzór bitowy to "00000000", zmieni jej wzór na "11111111". "

Więc jeśli int a = 60 (0011 1100), to int c = ~a (1100 0011).

Pytanie brzmi, w jaki sposób Java oblicza liczby ujemne, tak aby 1100 0011 = -61? Jedynym sposobem 1100 0011 oblicza -61 jest

  1. najwyższy bit jest bitem znaku.
  2. -2^6 + 2^1 + 2^0 = -61.

Ale to nie ma dla mnie żadnego sensu.

+3

You jest na właściwej ścieżce, z najwyższym bitem będącym bitem znaku. Zobacz [Uzupełnienie dwóch] (http://en.wikipedia.org/wiki/Two's_complement). – rgettman

+0

bit będący sygnaturą jest używany dla double i float, co oznacza, że ​​masz 0,0 i -0,0, liczby całkowite nie są wykonywane w ten sposób, a 'char' jest unsigned. –

Odpowiedz

12

Założenie, że najwyższy bit to prosty bit znaku , to zła. Java, a także większość współczesnych języków programowania (i architektury sprzętowej) używa tak zwanej reprezentacji liczbowej w postaci two's complement. (Sam bit, przypadkowo, wskazuje znak, ale nie w taki sposób, w jaki byś tego oczekiwał, tj. 150 i -150 mają więcej różnic niż tylko bit znaku w ich reprezentacji.)

Ta reprezentacja może wydawać się najpierw dziwny wybór, ale w rzeczywistości automatyzacja operacji, takich jak dodawanie liczby dodatniej do liczby ujemnej (lub jej odmian), nie wymaga od procesora sprawdzania specjalnych przypadków.

Według the relevant Wikipedia article:

System jest przydatny w uproszczeniu realizacji arytmetyki na sprzęcie komputerowym. Dodanie od 0011 (3) do 1111 (-1) na początku wydaje się dawać błędną odpowiedź 10010. Jednak sprzęt może po prostu zignorować lewy skrajny bit, aby dać poprawną odpowiedź 0010 (2). Wciąż muszą istnieć kontrole przepełnienia w celu przechwycenia operacji, takich jak zsumowanie 0100 i 0100. System umożliwia zatem dodanie ujemnych argumentów bez obwodu odejmującego i obwodu, który wykrywa znak liczby. Co więcej, ten obwód dodatkowy może również wykonywać odejmowanie, biorąc dwójkę uzupełnienia liczby (patrz poniżej), która wymaga tylko dodatkowego cyklu lub własnego obwodu sumatora. Aby to wykonać, obwód jedynie udaje, że istnieje dodatkowy lewy skrajny bit 1.

See this related answer for an even more in-depth explanation with lots of nice, easy to understand examples.

3

Java primitive numeral data types - int, long, byte i short są reprezentowane w two's complement.Co to oznacza:

  • Wartość najwyższa jest wynikiem wszystkich bitów ustawionych na 1, z wyjątkiem MSB.
    • przykład: 0111 1111 = 127
  • MSB ustawiony jest na 1, a wszystkie pozostałe bity ustawione na 0 jest najniższa wartość.
    • Przykład: 1000 0000 = -128

Jedynym minusem jest tutaj wartość MSB, więc jeśli rozbicie go na tej reprezentacji, będziemy przybyć -61:

|-128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 | 
| 1 | 1 | 0 | 0 | 0 | 0 | 1 | 1 | 

-128 + 64 + 2 + 1 = -61. 
Powiązane problemy