Pergunta

Eu estava a digitalização de um código fonte de terceiros usando Findbugs (apenas para ser cauteloso antes de integrar a ele o meu), e encontrou o seguinte aviso:

long a = b << 32 | c

Bug: mudança Integer id por 32 Padrão: ICAST_BAD_SHIFT_AMOUNT, digite: BSHIFT, categoria: CORREÇÃO

O código executa um deslocamento por inteiro uma quantidade constante fora da faixa 0..31. O efeito disto é a utilização dos mais baixos 5 bits do valor inteiro decidir quanto a mudar por. este provavelmente não é falta era esperado, e -lo pelo menos confuso.

Alguém poderia explicar o que exatamente faz o médio acima?

Obrigado! (Estou muito um novato em programação Java)

Foi útil?

Solução

A partir da Java Specification Language :

Se o tipo promovido da mão esquerda operando é int, apenas os cinco bits de ordem mais baixa do lado direito operando são usados ??como a distância turno. É como se a mão direita operando foram submetidos a um operador bit a bit lógico AND & (§15.22.1) com o valor da máscara 0x1f. A distância mudança realmente usado é, portanto, sempre na faixa de 0 a 31, inclusive.

Então, se b é um int, a expressão é idêntica à

long a = b | c;

que eu altamente dúvida é o que se pretende. Ele deveria ter sido

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

(Se b é já uma longa, o código está correto e FindBugs é confundido sobre o bug).

Outras dicas

Editado: O problema quase certamente decorre do fato de que 'b' é um 'int' e não uma 'long'

.

Em C, se 'b' é um inteiro em vez de um longo e você desvio para a esquerda por 32 bits, todos os bits do valor original foram removidos, de modo que o resultado da expressão global seria a mesma como 'c' você invocar um comportamento indefinido, portanto, qualquer resultado é permissível. Java define as coisas de forma diferente - como observado no comentário por Rasmus Faber e a resposta escolhida - e faz mudanças overlong módulo o número máximo de bits que podem ser deslocados. [Parece uma maneira estranha de fazer negócios; Eu provavelmente teria arranjado para uma exceção em uma linguagem que eles tem. No entanto, é claramente definido, o que é mais importante do que exatamente o que a definição é] A coerção para 64-bits não ocorre quando a expressão é avaliada.; ela ocorre quando a expressão é completa e a atribuição acontece.

A referência a 5 bits é ... intrigante. Isso significa que se você mudar deixado por, digamos, 48 ??ou binário 110000, é o mesmo como mudar deixado por 16. Ou, em alternativa, 'x << n' é o mesmo que 'x << (n % 32)'.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top