Operador de divisão Java

pessoal como funciona esse operador de divisão ‘>> 4’?
um exemplo q vi tinha assim…
int xfinal = xstart+(Game.WIDTH >>4);

Esse é o operador de signed right shift. O que isto faz é pegar no numero convertido para binário e deslocar os bits para a direita tantas posições quanto o número indicado, preenchendo à esquerda com o bit de signal (0 para positivos e 1 para negativos)

Por exemplo, se tivermos 26 >> 2:

26 ==> 0001 1010
deslocando os bits dois para a direita (os que estiverem mais à direira desaparecem e preenchendo à esquerda com 0), ficamos com
0000 0110 ==> 6

Então 26 >> 2 = 6

Com números negativos
-26 >> 2
-26 ==> 1110 0110
Deslocando para direita (mas preenchendo com 1) ficamos com 1111 1001, que é -7

Então -26 >> 2 = -7

2 curtidas

Na verdade o >> é um operador bit shift (veja este tutorial da Oracle).

Para ser mais preciso, a especificação da linguagem chama esse operador de “signed right shift”. E como o próprio nome diz, ele faz o deslocamento dos bits para a direita.

Por exemplo, o número 38 em binário corresponde a 00100110. Se fizermos 38 >> 4, significa que os bits deverão ser deslocados 4 posições para a direita. Ou seja:

00100110  <- valor original (38)
00000010  <- deslocando 4 posições para a direita

Repare que os últimos 4 bits (0110) são perdidos com o deslocamento. E à esquerda, eles vão sendo preenchidos com zeros. O resultado é 00000010, que equivale ao número 2 (que é o mesmo resultado de 38 / 16).


Então na verdade esse não é exatamente um operador de divisão. Em alguns casos ele pode ser equivalente, mas com ressalvas, veja mais sobre isso no final.

Esqueça os números binários por enquanto. Imagine os números na base 10 (aqueles “normais” que todos usam no dia-a-dia).

Se eu tenho o número 457090, e quero dividir por 1000 (desconsiderando o resto da divisão e as casas decimais), basta eu eliminar os 3 últimos dígitos, resultando em 457.

Basicamente, se eu elimino apenas 1 dígito do final (45709), é o mesmo que dividir por 10. Se eu elimino 2 dígitos do final (4570) é o mesmo que dividir por 100 (ou por 102), se eu elimino 3 dígitos do final (457) é o mesmo que dividir por 1000 (ou por 103) e assim por diante.

De maneira geral, se eu eliminar N dígitos do final, é o mesmo que dividir o número por 10N. Mas isso só vale se o número estiver na base 10.

Generalizando essa regra, se um número está representado na base B e eu eliminar N dígitos do final, o resultado é o mesmo que dividir esse número por BN.

Então se o número estiver na base 2, e eu deslocar 4 posições para a direita (que é o mesmo que eliminar os 4 últimos dígitos), então o resultado é o mesmo que dividir esse número por 24 (ou seja, o mesmo que dividir por 16).


Mas tem um porém

Isso tudo que falei só serve para números positivos. Se o número for negativo (e isso é indicado pelo primeiro bit, que em números negativos é igual a 1), aí já não é mais equivalente. Por exemplo, se o número for -38 teremos o seguinte:

int n = -38;
System.out.println(n / 16); // -2
System.out.println(n >> 4); // -3

Isso porque os bits agora são assim:

11111111111111111111111111011010  <- valor original (-38)
11111111111111111111111111111101  <- deslocar 4 posições para a direita (-3)

Ao deslocar para a direita, as posições da esquerda mantém o sinal. No caso de números positivos, o primeiro bit é zero, então ao deslocar para a direita, as posições da esquerda são preenchidos com zero. Mas em números negativos o primeiro bit é 1, e o sinal é mantido ao fazer o right shift (aliás, é por isso que o operador se chama “signed rigth shift” - “signed” indica que é “com sinal”, ou seja, o sinal é levado em conta ao se fazer o shift).

O resultado só dá igual se a divisão é exata (por exemplo, se fosse -32, ambos resultariam em -2).


Só por curiosidade, existe também um unsigned right shift (>>>), que sempre preenche as posições da esquerda com zeros (para números positivos, vai continuar sendo equivalente à divisão, mas para negativos dará um resultado completamente diferente).

3 curtidas

Complementando a ótima explicação do @hugokotsubo, se por ventura ainda não ficou claro o deslocamento, segue um passo a passo deslocando 4 bits:

00100110 <- valor original (38)
00010011 <- deslocando 1 bit para a direita
00001001 <- deslocando 2 bits para a direita
00000100 <- deslocando 3 bits para a direita
00000010 <- deslocando 4 bits para a direita
1 curtida

Na verdade são sempre divisões por potencias de dois, quer para positivos, quer para negativos, arredondando sempre para o menor inteiro
-38/16 = -2.375 (arredondando dá -3)

não esquecer que o menor inteiro negativo é o de maior valor absoluto

3 curtidas

obrigado!