2010-10-16 4 views

Répondre

32

Le problème est que tous les arguments sont d'abord promus int avant l'opération de changement a lieu:

byte b = (byte) 0xf1; 

b est signé, donc sa valeur est -15.

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

b premier signe est étendu au--15 = 0xfffffff1 entier, alors décalé vers la droite pour 0xffffffff et tronquée à 0xff par la fonte à byte.

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

b premier signe est étendu au--15 = 0xfffffff1 entier, alors décalé vers la droite pour 0x0fffffff et tronquée à 0xff par la fonte à byte. Vous pouvez effectuer (b & 0xff) >>> 4 pour obtenir l'effet désiré.

+12

Oh Dieu Java est tellement brisé - qui était le trou du cul qui a dit que l'arithmétique non signée était trop complexe pour les programmeurs à comprendre? –

+1

@PP L'absence de nombres non signés en Java n'est pas un problème (sauf pour la division entière, et cela sera finalement corrigé dans JDK 8): http://stackoverflow.com/questions/397867/port-of-random-generator -from-c-à-java/397997 # 397997 – starblue

3

Je suppose que b est étendu à int avant de changer de position.

Donc cela pourrait fonctionner comme prévu:

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

Selon Bitwise and Bit Shift Operators:

L'opérateur de décalage droit non signé ">>>" décale un zéro dans la position extrême gauche, tandis que la position extrême gauche après ">>" dépend de l'extension du signe.

Donc, avec b >> 4 vous transformez 1111 0001-1111 1111 (b est négatif, il ajoute 1) qui est 0xff.

0

Java essaie de ne pas avoir de support explicite pour les types de base non signés en définissant les deux opérateurs de décalage différents à la place.

La question parle de décalage droit non signé, mais les exemples le font (signés et non signés), et montre la valeur du décalage signé (>>).

Vos calculs seraient corrects pour un décalage non signé (>>>).

Questions connexes