"Si un trabajador quiere hacer bien su trabajo, primero debe afilar sus herramientas." - Confucio, "Las Analectas de Confucio. Lu Linggong"
Página delantera > Programación > ## ¿Por qué el operador de turno correcto muestra un comportamiento inesperado con valores de turno grandes?

## ¿Por qué el operador de turno correcto muestra un comportamiento inesperado con valores de turno grandes?

Publicado el 2024-11-04
Navegar:809

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

Comportamiento intrigante del operador de desplazamiento a la derecha

El operador de desplazamiento a la derecha (>>) exhibe un comportamiento peculiar cuando se trata de valores grandes de desplazamiento a la derecha. Considere el siguiente 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) 

El resultado esperado para foo(1, 32) sería 0, pero sorprendentemente devuelve 1. Esto se puede atribuir a lo siguiente:

Desplazamiento lógico versus aritmético Shift

En arquitecturas x86/x86-64, el operador de desplazamiento a la derecha en realidad realiza un desplazamiento lógico a la derecha, lo que significa que llena los bits vacantes con 0, independientemente del signo del operando izquierdo. El comportamiento es similar a usar un >>> b.

Optimización del compilador

En el caso de foo(1, 32), el valor 32 se convierte a int, que efectivamente se trunca a 32 bits. Dado que el valor máximo que puede contener un int es 231-1, el desplazamiento hacia la derecha es esencialmente un >>> (32 % 32), que se evalúa como 0.

Indefinido Comportamiento

El estándar C relevante establece que "el comportamiento no está definido" para desplazamientos a la derecha con un recuento mayor o igual al ancho del operando izquierdo promocionado. En este caso, tanto 1 >> 32 como (int)1 >> (int)32 tienen un recuento mayor que 32, lo que genera resultados impredecibles.

Diferencia con la barra(1, 32)

La barra de funciones toma un entero sin signo de 64 bits, que se garantiza que tendrá un ancho mayor que 32. Por lo tanto, el desplazamiento hacia la derecha en la barra no se ve afectado por un comportamiento indefinido.

Conclusión

El comportamiento del operador de desplazamiento a la derecha se vuelve ambiguo cuando se trata de valores de desplazamiento grandes. En arquitecturas x86/x86-64, se realiza un desplazamiento lógico a la derecha, mientras que en ARM se puede utilizar una implementación diferente. Debido al comportamiento indefinido, el resultado de desplazamientos a la derecha con un recuento mayor o igual al ancho del operando debe evitarse en el código portátil.

Último tutorial Más>

Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.

Copyright© 2022 湘ICP备2022001581号-3