2010-10-16 23 views
18

java aşağıdaki kod snip düşünün değişken bayt için uygulananDavranış

byte b=(byte) 0xf1; 
byte c=(byte)(b>>4); 
byte d=(byte) (b>>>4); 

çıkışı:

c=0xff 
d=0xff 

beklenen çıkışı:

c=0x0f 

nasıl? olarak b işaretsiz sağa kayması sonrasında 1111 0001 ikili 0000 1111 dolayısıyla 0x0f ama neden 0xff nasıl?

+3

Belki de bayt, int ilk satır – CodesInChaos

cevap

32

sorun vardiya çalışması gerçekleşmeden önce tüm argümanlar ilk int terfi olmasıdır.

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

b ilk işareti genişletilmiş tamsayı -15 = 0xfffffff1, sonra byte için dökme 0xff için 0xffffffff ve tepe bölümü kesik doğru kaydınlır.

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

b ilk işareti genişletilmiş tamsayı -15 = 0xfffffff1, sonra byte için dökme 0xff için 0x0fffffff ve tepe bölümü kesik doğru kaydınlır.

Sen istenen etkiyi elde etmek için (b & 0xff) >>> 4 yapabilirsiniz.

+12

için genişletilmiş Oh Tanrı Java çok bozuk - kim imzasız aritmetik programcılar anlamak için çok karmaşık olduğunu söyledi pislik oldu kim? –

+1

@PP Java'da imzalanmamış numaraların olmaması bir sorun değildir (tamsayı bölme dışında ve son olarak JDK 8'de düzeltilecektir): http://stackoverflow.com/questions/397867/port-of-random-generator uçtan uca entegre c-için-java/397.997 # 397.997 – starblue

3

Ben b kayması önce int uzatıldı işareti olduğunu tahmin ediyorum.

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

göre Bitwise and Bit Shift Operators için:

Yani bu beklendiği gibi işe yarayabilecek,

işaretsiz sağa kaydırma operatörü ">>>" en soldaki pozisyonuna sıfır vardiya en soldaki konumda iken ">>" den sonra işaret uzantısına bağlıdır. (Bu 1 ekler böylece b negatiftir)

Yani b >> 4 ile size 0xff olan 1111 1111 için 1111 0001 dönüşümü.

byte b = (byte) 0xf1; 

b imzalanır, böylece onun değerini -15 geçerli:

0

Java yerine iki farklı vardiya operatörleri tanımlayarak imzasız temel tipleri için açık destek olan eksik çalışır.

işaretsiz sağa kayma ile ilgili soru görüşmeler, ancak örnekler her ikisi (imzalı ve imzasız) yapar ve imzalı vardiya değerini gösterir (>>).

Hesaplarınız imzasız kayma için doğru olacaktır (>>>).