Pregunta

Estaba escaneando un código fuente de terceros usando Findbugs (solo para ser cauteloso antes de integrarlo en el mío), y encontré la siguiente advertencia:

long a = b << 32 | c
  

Error: Cambio de número entero por 32 Identificación del patrón:   ICAST_BAD_SHIFT_AMOUNT, escriba: BSHIFT,   categoría: CORRECCIÓN

     

El código realiza un cambio de número entero por   una cantidad constante fuera del rango   0..31. El efecto de esto es usar los 5 bits inferiores del valor entero   para decidir cuánto cambiar. Esta   probablemente no se esperaba lo que se esperaba, y   es al menos confuso.

¿Alguien podría explicar qué significa exactamente lo anterior?

¡Gracias! (Soy un novato en programación Java)

¿Fue útil?

Solución

Del Especificación del lenguaje Java :

  

Si el tipo promocionado del operando de la izquierda es int, solo se usan los cinco bits de orden más bajo del operando de la derecha como la distancia de desplazamiento. Es como si el operando de la derecha estuviera sujeto a un operador AND lógico bit a bit & amp; (§15.22.1) con el valor de máscara 0x1f. Por lo tanto, la distancia de desplazamiento realmente utilizada siempre está en el rango de 0 a 31, inclusive.

Entonces, si b es un int, la expresión es idéntica a

long a = b | c;

que dudo mucho es lo que se pretende. Probablemente debería haber sido

long a = ((long) b << 32) | c;

(si b ya es largo, el código es correcto y FindBugs está equivocado sobre el error).

Otros consejos

Editado: El problema casi seguramente se debe al hecho de que 'b' es un 'int' y no un 'largo'.

En C, si 'b' es un número entero en lugar de un largo y se desplaza a la izquierda 32 bits, todos los bits del valor original se han eliminado, por lo que el resultado de la expresión general sería el mismo como 'c' invocaría un comportamiento indefinido, por lo que cualquier resultado es permisible. Java define las cosas de manera diferente, como se señala en el comentario de Rasmus Faber y la respuesta elegida, y realiza un cambio excesivo de módulos el número máximo de bits que se pueden cambiar. [Parece una forma extraña de hacer negocios; Probablemente habría arreglado una excepción en un idioma que los tenga. Sin embargo, está claramente definido, lo cual es más importante que exactamente cuál es la definición.] La coerción a 64 bits no ocurre mientras se evalúa la expresión; ocurre cuando la expresión se completa y se realiza la asignación.

La referencia a 5 bits es ... intrigante. Significa que si se desplaza a la izquierda por, digamos, 48, o 110000 binario, es lo mismo que desplazarse a la izquierda por 16. O, alternativamente, ' x < < n 'es lo mismo que' x < < (n% 32) '.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top