"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > ## Por que o operador de deslocamento para a direita exibe um comportamento inesperado com valores de deslocamento grandes?

## Por que o operador de deslocamento para a direita exibe um comportamento inesperado com valores de deslocamento grandes?

Publicado em 2024-11-04
Navegar:113

## Why Does the Right Shift Operator Exhibit Unexpected Behavior with Large Shift Values?

Comportamento intrigante do operador de deslocamento para a direita

O operador de deslocamento para a direita (>>) exibe um comportamento peculiar ao lidar com grandes valores de deslocamento para a direita. Considere o seguinte programa:

#include 
#include 

int foo(int a, int b)
{
   return a >> b;
}

int bar(uint64_t a, int b)
{
   return a >> b;
}

int main()
{
    std::cout > 32: " > 32) > (int)32: " > (int)32) 

A saída esperada para foo(1, 32) seria 0, mas surpreendentemente, ele retorna 1. Isso pode ser atribuído ao seguinte:

Mudança Lógica vs. Shift

Em arquiteturas x86/x86-64, o operador de deslocamento para a direita está na verdade executando um deslocamento lógico para a direita, o que significa que ele preenche os bits vagos com 0, independentemente do sinal do operando esquerdo. O comportamento é semelhante ao uso de >>> b.

Otimização do compilador

No caso de foo(1, 32), o valor 32 está sendo convertido para int, que é efetivamente truncado para 32 bits. Como o valor máximo que um int pode conter é 231-1, o deslocamento para a direita é essencialmente um >>> (32% 32), que é avaliado como 0.

Indefinido Comportamento

O padrão C relevante afirma que "o comportamento é indefinido" para deslocamentos à direita com uma contagem maior ou igual à largura do operando esquerdo promovido. Nesse caso, 1 >> 32 e (int)1 >> (int)32 têm uma contagem maior que 32, levando a resultados imprevisíveis.

Diferença com bar(1, 32)

A barra de funções usa um número inteiro não assinado de 64 bits, que tem largura garantida maior que 32. Portanto, o deslocamento para a direita na barra não é afetado por comportamento indefinido.

Conclusão

O comportamento do operador de deslocamento para a direita torna-se ambíguo ao lidar com grandes valores de deslocamento. Nas arquiteturas x86/x86-64, um deslocamento lógico à direita é executado, enquanto no ARM, uma implementação diferente pode ser usada. Devido ao comportamento indefinido, o resultado de deslocamentos à direita com contagem maior ou igual à largura do operando deve ser evitado em código portátil.

Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3