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 variablebyte
en LHS. De lo contrario, tenemos que hacer unExplicit 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): -
-
varInt1
contiene inicialmente 3 . Entonces el valor de RHS se evalúa a 64 . Aunque este valor puede acomodarse a la variablebyte
en LHS , pero el compilador también sabe que, es posible cambiar el valor devarInt1
... Entonces, ¿quévarInt1
si el valor devarInt1
se cambia a 4 en algún momento? No funcionará entonces .. Por eso no está permitido ... - Ahora, en este caso, dado que aquí hemos usado explícitamente un
Integer Literal
, el compilador está seguro de que se acomodará enbyte
. Por lo tanto, permite la conversiónimplicit
. - Nuevamente, en este caso, se sabe que
RHS
evaluará a128
que no se puede acomodar enbyte
. 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.
En este caso, el compilador ve que,
finalVarInt2
contiene el valor 3 . Entonces, RHS evalúa a 64 , que puede acomodarse en la variablebyte
en LHS . Ahora, dado que la variable esfinal
, no se puede cambiar, y elCompiler
sabe, por lo que es seguro que t * su valor siempre será64
* ... Así que el compilador lo permite.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 enbyte
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.