class TesteShift {
public static void main (String[] args) {
int a = (-11) >> 2; // O valor resultante é -3
System.out.println (a);
int b = (-11) >>> 2; // O valor resultante é 1073741821, ou em hexadecimal, 3ffffffd
System.out.println (b);
}
}
Convertendo o valor -11 para binário (int de 32 bits)
A princípio, vamos converter o valor +10 para binário (você tem de pegar
o número original, tirar o sinal (-11 -> +11), e subtrair 1.
Converter +10 para binário dá (a conversão para binário fica como exercício):
1010
A seguir, vamos completar com zeros à esquerda até dar 32 bits
(pus uns pontos de 4 em 4 para ficar mais fácil de contar os bits):
0000.0000.0000.0000.0000.0000.0000.1010
Agora, vamos inverter todos os bits (o que é 0 passa para 1 e vice-versa):
1111.1111.1111.1111.1111.1111.1111.0101
Efetuando o shift ">>"
O shift ">>" insere à esquerda uma cópia do bit mais significativo (o que fica mais à esquerda), e empurra os outros bits, jogando fora os bit menos significativos (os que ficam mais à direita). Como você especificou ">> 2", então ele pega e faz esse processo duas vezes.
Portanto,
como 1111.1111.1111.1111.1111.1111.1111.0101 começa com 1, então é o 1 que vai ser copiado.
Isso fica:
11.1111.1111.1111.1111.1111.1111.1111.0101
Ou seja, no final fica:
1111.1111.1111.1111.1111.1111.1111.1111.1101
Convertendo o valor 1111.1111.1111.1111.1111.1111.1111.1111.1101 para decimal
Como o bit mais significativo é 1, então é um valor negativo. Nesse caso, devemos fazer o seguinte:
- Inverter todos os bits (veja que é o processo inverso do que foi feito acima)
Isso dá:
1111.1111.1111.1111.1111.1111.1111.1101
=>
0000.0000.0000.0000.0000.0000.0000.0010
E como você deve saber, isso em decimal dá 2.
- E agora vamos somar 1 (veja que é o processo inverso do que foi feito acima)
2 + 1 = 3
OU seja, o valor 1111.1111.1111.1111.1111.1111.1111.1111.1101 é -3.
Efetuando o shift ">>>"
O shift ">>>" insere à esquerda um bit 0, e empurra os outros bits, jogando fora os bit menos significativos (os que ficam mais à direita). Como você especificou ">> 2", então ele pega e faz esse processo duas vezes.
Portanto,
Isso fica:
00.1111.1111.1111.1111.1111.1111.1111.0101
Ou seja, no final fica:
0011.1111.1111.1111.1111.1111.1111.1111.1101
Convertendo o valor 0011.1111.1111.1111.1111.1111.1111.1111.1101 para decimal
Como o bit mais significativo é 0, então é um valor positivo.
Portanto, você pode converter esse valor diretamente de binário para decimal - só que você precisa ter um bocado de paciência. O resultado, em decimal, é 1.073.741.821.
Você viu que as contas são chatas, e não dá para fazer um truque quando os números são negativos (quando os números são positivos é fácil, porque é só dividir por uma potência de 2). Portanto isso não deve cair na sua certificação Java.