O que são operadores de turno bitwise (bit-shift) e como eles funcionam?
I'tenho tentado aprender C no meu tempo livre, e outras linguagens (C#, Java, etc.) têm o mesmo conceito (e muitas vezes os mesmos operadores) ...
O que eu'estou me perguntando é, a um nível central, o que faz o bit-shifting (<<
, >>
, >>>>
), que problemas ele pode ajudar a resolver, e o que gotchas espreitam na curva? Em outras palavras, um guia absoluto para principiantes's para a mudança de bits em toda a sua bondade.
1334
3
Os operadores de mudança de bits fazem exactamente o que o seu nome implica. Eles mudam os bits. Aqui está uma breve (ou não-tão-briefe) introdução aos diferentes operadores de mudança de bit.
Os Operadores
>>
é o operador de turno direito aritmético (ou assinado).>>>
é o operador lógico (ou não assinado) do turno da direita.O deslocamento aritmético direito é exatamente como o deslocamento lógico direito, exceto que ao invés de estofar com zero, ele estoca com o bit mais significativo. Isto porque o bit mais significativo é o bit sign, ou o bit que distingue números positivos e negativos. Ao almofadar com o bit mais significativo, o deslocamento aritmético para a direita é o sinal-preservante.
Por exemplo, se interpretarmos este padrão de bits como um número negativo:
temos o número -2.147.483.552. Mudando isso para a direita 4 posições com o deslocamento aritmético (-2.147.483.552 >> 4) nos daria:
ou o número -134.217.722.
Assim, vemos que preservamos o sinal de nossos números negativos usando o deslocamento aritmético direito, ao invés do deslocamento lógico direito. E mais uma vez, vemos que estamos a fazer a divisão por poderes de 2.
Digamos que temos um único byte:
Aplicar um único bitshift para a esquerda nos leva:
O zero mais esquerdo foi deslocado para fora do byte, e um novo zero foi anexado à extremidade direita do byte.
Os pedaços não rolam; eles são descartados. Isso significa que se você sair do turno 1101100 e depois do turno da direita, você não terá o mesmo resultado de volta.
O deslocamento à esquerda por N é equivalente a multiplicar por 2N.
Mudar para a direita por N é (se você estiver usando [um complemento][1]) é o equivalente a dividir por 2N e arredondar para zero.
O bitshifting pode ser usado para multiplicação e divisão insanamente rápidas, desde que você esteja trabalhando com um poder de 2. Quase todas as rotinas gráficas de baixo nível usam o bitshifting.
Por exemplo, antigamente, utilizávamos o modo 13h (320x200 256 cores) para os jogos. No modo 13h, a memória de vídeo era disposta sequencialmente por pixel. Isso significava que para calcular a localização de um pixel, você usaria a seguinte matemática:
Agora, naquele tempo, a velocidade era crítica, por isso usávamos os bitshifts para fazer esta operação.
No entanto, 320 não é um poder de dois, por isso para contornar isso temos de descobrir o que é um poder de dois que somados juntos faz 320:
Agora podemos converter isso em turnos de esquerda:
O que se entende é que o seguinte é dependente da implementação (de acordo com a norma ANSI):
x pode agora ser 127 (01111111) ou ainda -1 (1111111111).
Na prática, normalmente é a última.