2009-02-19 20 views
10
byte x = -1; 
for(int i = 0; i < 8; i++) 
{ 
    x = (byte) (x >>> 1); 
    System.out.println("X: " + x); 
} 

Jak rozumiem, java przechowuje dane w uzupełnieniu do dwóch elementów, co oznacza -1 = 11111111 (według Wikipedii).manipulacja bitem java

Również z dokumentacji java: "Wzorzec bitowy jest podany przez lewy operand, a liczba pozycji do przesunięcia przez prawy operand Operatory przesuniętej prawej prawej zmiany" >>> "przesunięcia zero do najbardziej wysuniętej na lewo pozycji, natomiast najbardziej wysunięta na lewo pozycja po ">>" zależy od przedłużenia znaku. "

Co oznacza, że ​​>>> przesuwa zawsze 0 w lewo najbardziej za każdym razem. Więc spodziewać ten kod do być

iteracja: nieco reprezentacja x

0: 11111111

1: 01111111

2: 00111111

3: 00011111

. ..to na

Jednak moje wyniki to alwa ys X: -1, co oznacza (myślę), że >>> umieszcza bit znaku w lewej pozycji najbardziej. Więc wtedy spróbuję >> i ten sam rezultat.

Co się dzieje? Oczekuję, że moje wyniki będą: X: -1, x: 127, x: 63, itd.

+0

Jest to jeden z problemów w Javie Puzzlers. – starblue

Odpowiedz

27

Kto myślał, że bajty powinny być podpisane, gdy wynaleziono Java powinny być wyjęte i bity z mokrym kijem selera aż wołają :-)

Możesz robić co chcesz, oddając do int i zapewnienie, że nigdy przesunąć 1 do górnego kawałka, coś takiego:

byte x = -1; 
int x2 = ((int)x) & 0xff; 
for(int i = 0; i < 8; i++) 
{ 
    x2 = (x2 >>> 1); 
    System.out.println("X: " + x2); 
} 

Twój szczególny problem, ponieważ jest to >>> odlewania do int zrobić przejście, to jesteś rzucając go z powrotem do bajt, jak pokazano tutaj:

byte x = -1; 
int x2 = ((int)x) & 0xff; 
int x3; 
int x4 = x2; 
for(int i = 0; i < 8; i++) 
{ 
    x2 = (x2 >>> 1); 
    System.out.println("X2: " + x2); 
    x3 = (x >>> 1); 
    x = (byte)x3; 
    x4 = (x4 >>> 1); 
    System.out.println("X: " + x3 + " " + x + " " + x4); 
} 

które wyjścia:

X2: 127 
X: 2147483647 -1 127 
X2: 63 
X: 2147483647 -1 63 
X2: 31 
X: 2147483647 -1 31 
X2: 15 
X: 2147483647 -1 15 
X2: 7 
X: 2147483647 -1 7 
X2: 3 
X: 2147483647 -1 3 
X2: 1 
X: 2147483647 -1 1 
X2: 0 
X: 2147483647 -1 0 

można wyraźnie zobaczyć, że x i x3 nie działa (choć x3 przesuwa się prawidłowo, rzucając go z powrotem do bajta w x ustawia go ponownie -1). x4 działa idealnie.

+0

chociaż to działa (doceniam pomoc) nie wyjaśnia mi, dlaczego mój kod nie działa. – jbu

+0

Zobacz aktualizację, która wyjaśnia to lepiej. – paxdiablo

+0

Tak, dziękuję! – jbu

3

Nie jestem tego pewien. Ale domyślam się, że

x >>> 1 

pobiera promowany do int od bajta, ponieważ dosłowne „1” jest int. To, co obserwujesz, ma sens.

+0

Nie sądzę .. Zmieniłem kod, aby upewnić się, że nie został awansowany na int: bajt x = -1; dla (int i = 0; i <8; i ++) { x = (bajt) ((bajt) x >> (bajt) 1); System.out.println ("X:" + x); } wyjściowa była taka sama, X: -1 za każdym razem – jbu

+0

to nie pomoże - na pewno, konwertowanie X i 1 do bajtach, ale Java automatycznie konwertuje je z powrotem do int przed nałożeniem właściwej operatorem przesunięcia. Nie ma możliwości bezpośredniego zastosowania przesunięcia bitowego do bajtów, o ile wiem. –

0

Nie wiem, dlaczego to nie działa, ale to prosty sposób, aby usunąć górny kawałek jest & z (binarne) 0111111:

x = (byte) (x >>> 1) & 0x7F; 
5

Pamiętaj, że:

  • operandy operacje bitowe są zawsze promowane do co najmniej int!
  • odlewy zawsze obejmują rozszerzenie znaku.

Więc jeśli to zrobisz (x >>> n), nawet jeśli zdefiniowałeś x jako bajt, dla celów przesunięcia, zostanie on najpierw przekonwertowany na int. Jeśli konwertowany bajt ma wartość ujemną, to wszystkie dodatkowe bity (tak, że lewe 24 bity wynikowej int) dodane, aby dodać je do int, zostaną ustawione na 1. Lub umieścić inaczej, jeśli oryginał bajt wynosił -1, rzeczą, którą faktycznie przesuwasz jest -1 jako int, tj. 32-bitowa liczba ze wszystkimi 32 bitami ustawionymi na 1. Przesunięcie tego prawa o 1-8 miejsc nadal spowoduje dno 8 bitów wszystko ustawione na 1, a więc po powrocie do bajtu, kończy się bajtem z wszystkimi 8 bitami ustawionymi na 1 lub innymi słowy bajtami o wartości -1.

0

Problem polega na tym, jak powiedziano wcześniej (dawno temu), że x zostanie podniesiony do int (wydłużony znak) przed wykonaniem zmiany.
Robi konwersję "bit-to-bit" powinien pomóc:

byte x = -1; 
for(int i = 0; i < 8; i++) 
{ 
    x = (byte) ((x & 0xFF) >>> 1); 
    System.out.println("X: " + x); 
} 
+0

Byłoby miło wiedzieć, dlaczego -1 ... –

Powiązane problemy