2010-10-16 11 views

Odpowiedz

32

Problemem jest to, że wszystkie argumenty są po raz pierwszy awansował do int zanim operacja ta zmiana zachodzi:

byte b = (byte) 0xf1; 

b jest podpisana, więc jego wartość jest -15.

byte c = (byte) (b >> 4); 

b jest pierwszą oznaką-przedłużony do całkowitej -15 = 0xfffffff1, następnie przesunięta w prawo do 0xffffffff i obcinane do 0xff przez obsady do byte.

byte d = (byte) (b >>> 4); 

b jest pierwszą oznaką-przedłużony do całkowitej -15 = 0xfffffff1, następnie przesunięta w prawo do 0x0fffffff i obcinane do 0xff przez obsady do byte.

Można zrobić (b & 0xff) >>> 4 aby uzyskać pożądany efekt.

+12

O Boże, Jawa jest tak popsuta - kto był dupkiem, który powiedział, że niepodpisana arytmetyka jest zbyt skomplikowana, aby programiści ją zrozumieli? –

+1

@PP Brak numerów bez znaku w Javie nie stanowi problemu (z wyjątkiem podziału na liczby całkowite, które zostanie ostatecznie naprawione w JDK 8): http://stackoverflow.com/questions/397867/port-of-random-generator -z-c-do-java/397997 # 397997 – starblue

3

Przypuszczam, że b jest znak rozszerzony int przed zmianą biegu.

Więc to może działać zgodnie z oczekiwaniami:

(byte)((0x000000FF & b)>>4) 
1

Według Bitwise and Bit Shift Operators:

niepodpisany prawo operator shift ">>>" przesunięcia zera do skrajnej lewej pozycji, natomiast w lewej skrajnej pozycji po „>>” zależy na przedłużeniu migowego.

Więc z b >> 4 przekształcić 1111 0001 do 1111 1111 (b jest ujemna, więc dołącza 1), który jest 0xff.

0

Java próbuje skąpić na posiadające wyraźne poparcie dla niepodpisanych podstawowych typów poprzez zdefiniowanie dwóch różnych operatorów shift zamiast.

kwestia rozmowy o niepodpisane prawym przesunięcia, ale nie oba przykłady (podpisane i niepodpisane) i pokazuje wartość podpisanej Shift (>>).

Twoje obliczenia byłoby prawo do zmiany bez znaku (>>>).