Cambio a la izquierda con un recuento de cambio negativo

¿Qué pasa exactamente aquí?

a << -5

Obviamente no se desplaza a la derecha. Pero el libro que estoy leyendo dice:

En una máquina, esta expresión hace un desplazamiento a la izquierda de 27 bits

Mi pregunta es; ¿por qué? ¿Qué causa un desplazamiento a la izquierda de 27 bits? ¿Y qué ocurre exactamente al cambiar con un recuento de turno negativo? Gracias.

Los enteros negativos en el lado derecho son comportamientos indefinidos en el lenguaje C.

ISO 9899: 2011 6.5.7 Operadores de cambio en bits:

Las promociones enteras se realizan en cada uno de los operandos. El tipo de resultado es el del operando izquierdo promovido. Si el valor del operando derecho es negativo o es mayor o igual que el ancho del operando izquierdo promovido, el comportamiento no está definido .

Como ya respondieron otros miembros, produce un comportamiento indefinido. Lo que me gustaría mencionar aquí es que citas del libro (“En una máquina”) parece ser parcial. No generaliza el comportamiento. El libro también podría haber explicado que el comportamiento no está definido según el estándar. Por cierto, estaba pasando por “El nuevo estándar C – Un comentario económico y cultural” y encontré esta statement:

La instrucción Intel Pentium SAL (generada por gcc y Microsoft C ++ para evaluar los cambios a la izquierda) solo utiliza los cinco bits inferiores de la cantidad de desplazamiento

Esto explica muy bien por qué un desplazamiento a la izquierda de -5 podría resultar en un desplazamiento a la izquierda de 27 (para la representación en 2 complementarios de números negativos)

El comportamiento no está definido.

En la aritmética binaria de 5 bits, two’s-complement -5 tiene la misma representación binaria que el signo sin signo +27, lo que probablemente explica esa plataforma en particular.

Si el valor que está cambiando es una variable de 32 bits, el desplazamiento -5 va en un “ciclo” y desplaza 27 hacia adelante. El cambio solo puede tener lugar de forma “sin firmar”.

 int main() { unsigned int a = 1; printf("%u\n",a<<(-1)); return 0; } 

La salida es 2147483648.

Aquí está mi suposición y validación: (¡solo asunción!)

1. El operando derecho "<<" debe estar sin firmar int tipo,

entonces, primero, el (int) "-1" se convertirá en (sin signo int) "-1". Causa int type es una representación de complemento de dos, el resultado será 2 ^ 32-1 (unsigned int)

2.Debido a que el número 2 ^ 32-1 es más grande que el dígito de desplazamiento máximo, 2 ^ 32 - 1 será el mod 32, que es igual a 27

También probé algunos otros números de operandos correctos, y los resultados del cálculo manual con las reglas asumidas serán los mismos con los productos de mi IDE.

Estoy tratando de encontrar algunos documentos oficiales de apoyo, que puedan verificar si mi suposición es correcta o no. Tal vez usted me puede decir.