2010-10-16 16 views

Respuesta

32

El problema es que todos los argumentos son promovidos primero en int antes de la operación de cambio se lleva a cabo:

byte b = (byte) 0xf1; 

b se firma, por lo que su valor es -15.

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

b es primero signo extendido al entero -15 = 0xfffffff1, a continuación, desplaza a la derecha a 0xffffffff y truncado a 0xff por el molde a byte.

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

b es primero signo extendido al entero -15 = 0xfffffff1, a continuación, desplaza a la derecha a 0x0fffffff y truncado a 0xff por el molde a byte.

Puede hacer (b & 0xff) >>> 4 para obtener el efecto deseado.

+12

Oh, Dios Java está tan roto. ¿Quién fue el gilipollas que dijo que la aritmética sin firma era demasiado compleja para que los programadores la entendieran? –

+1

@PP La ausencia de números sin signo en Java no es un problema (a excepción de la división entera, y que finalmente se solucionará en JDK 8): http://stackoverflow.com/questions/397867/port-of-random-generator -de-c-to-java/397997 # 397997 – starblue

3

Supongo que b es signo extendido a int antes de cambiar.

Así que esto podría funcionar como se esperaba:

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

Según Bitwise and Bit Shift Operators:

El operador de desplazamiento a la derecha sin signo ">>>" se desplaza un cero a la posición más a la izquierda, mientras que la posición más a la izquierda después de ">>" depende de la extensión de la señal.

Así que con b >> 4 a transformar 1111 0001-1111 1111 (b es negativo, por lo que añade 1) que es 0xff.

0

Java intenta escatimar en tener soporte explícito para tipos básicos sin signo definiendo los dos operadores de cambio diferentes en su lugar.

La pregunta se refiere al desplazamiento a la derecha sin signo, pero los ejemplos hacen tanto (firmado y sin firmar), y muestra el valor del cambio firmado (>>).

Tus cálculos serían los correctos para el cambio sin signo (>>>).

Cuestiones relacionadas