convertir bytes java int byte bit-shift

convertir - Java-cambio de bit con números enteros y bytes



int to bytes java (3)

Convierte tu línea de shifting a esto: -

byte bitMask = (byte)(0x8>>(byte)bitNumber);

Su RHS, es un int, necesita convertirlo en byte.

El código anterior funcionará bien. Con o sin la casting de bitNumber a byte

Entonces, también puedes tener:

byte bitMask = (byte)(0x8>>bitNumber);

Pero, aquí hay una pregunta: byte bitMask = 0x8>>3; funciona bien ... ¿Por qué es así?

Aquí hay algunos ejemplos para explicar el motivo de su funcionamiento y también el comportamiento con el final :

byte bitMask; int varInt1 = 3; final int finalVarInt2 = 3; final int finalVarInt3 = 4; bitMask = 0x8>>varInt1; // 1. Will not work. bitMask = 0x8<<3; // 2. Will work bitMask = 0x8<<4; // 3. Will not work bitMask = 0x8<<finalVarInt2; // 1. Will work bitMask = 0x8<<finalVarInt3; // 2. Will not work

Aquí hay algunos razonamientos que explican el comportamiento anterior:

  • El valor en el RHS se typecasted implícitamente solo si, el compilador está seguro de que podrá acomodar ese valor en la variable byte en LHS. De lo contrario, tenemos que hacer un Explicit type casting para decirle al compilador que, sabemos lo que estamos haciendo, solo hazlo por nosotros ...

Ahora consideremos todos los casos uno a uno (del código anterior (1-3, 1-2): -

  1. varInt1 contiene inicialmente 3 . Entonces el valor de RHS se evalúa a 64 . Aunque este valor puede acomodarse a la variable byte en LHS , pero el compilador también sabe que, es posible cambiar el valor de varInt1 ... Entonces, ¿qué varInt1 si el valor de varInt1 se cambia a 4 en algún momento? No funcionará entonces .. Por eso no está permitido ...
  2. Ahora, en este caso, dado que aquí hemos usado explícitamente un Integer Literal , el compilador está seguro de que se acomodará en byte . Por lo tanto, permite la conversión implicit .
  3. Nuevamente, en este caso, se sabe que RHS evaluará a 128 que no se puede acomodar en byte . Error de nuevo .

Los dos últimos casos son diferentes de las variables regulares ... Dado que se declaran final , no se pueden reinicializar. Por lo tanto, el compilador puede tomar una decisión basada en el valor asignado.

  1. En este caso, el compilador ve que, finalVarInt2 contiene el valor 3 . Entonces, RHS evalúa a 64 , que puede acomodarse en la variable byte en LHS . Ahora, dado que la variable es final , no se puede cambiar, y el Compiler sabe, por lo que es seguro que t * su valor siempre será 64 * ... Así que el compilador lo permite.

  2. En el último caso, el valor de finalVarInt3 es 4 .. Razonamiento similar .. No cabe en LHS , ya que RHS evalúa a 128 que no puede caber en byte

Considere el siguiente código (donde byteIndex es un int):

int bitNumber = b-(8*byteIndex); bitMask = 0x8>>(byte)bitNumber;

Esto genera el error

error: possible loss of precision

cuando se compila (byte requerido, encontrado int).

El código

int bitNumber = b-(8*byteIndex); bitMask = 0x8>>2;

compila bien

¿Cuál es el problema aquí y cómo puedo arreglar el primer ejemplo para permitir el cambio de bit por el valor int?

EDITAR: después de los comentarios, aquí hay un ejemplo más completo:

48) int byteIndex; 49) byte bitMask; 50) int bitNumber; // assign value to byteIndex 67) bitNumber = b-(8*byteIndex); 68) bitMask = 0x8>>bitNumber;

y el error es:

...MyClass.java:68: error: possible loss of precision bitMask = 0x8>>bitNumber; ^ required: byte found: int 1 error


De hecho, esta no es la respuesta, la respuesta correcta es la que Rohit Jain escribió, pero esta es la primera vez que veo este comportamiento de JVM, comparo estos códigos:

versión donde bitNumber está marcado como final

final int bitNumber = 10; final byte bitMask = 0x8 >> bitNumber;

versión donde bitNumber no es final

int bitNumber = 10; bitNumber = 10; final byte bitMask = 0x8 >> bitNumber;

Y hay un error es el segundo ejemplo, probablemente algo de optimización. Sería genial si alguien sabe el motivo ;-)


En su primer ejemplo, bitnumber es un int (32 bits), y cuando lo convierte como un byte (8 bits), está perdiendo los 24 bits de mayor orden. Por lo tanto, estás perdiendo precisión. Solo deja el molde (byte) apagado.