advertencia: recuento de desplazamiento a la izquierda> = ancho de tipo

2 minutos de lectura

avatar de usuario
Rupert Madden Abbott

Soy muy nuevo en el manejo de bits y me quedé atascado en la siguiente advertencia al compilar:

 7: warning: left shift count >= width of type

Mi línea 7 se ve así

unsigned long int x = 1 << 32;

Esto tendría sentido si el tamaño de long en mi sistema era de 32 bits. Sin embargo, sizeof(long) devoluciones 8 y CHAR_BIT Se define como 8 sugiriendo que long debería tener 8×8 = 64 bits de largo.

¿Que me estoy perdiendo aqui? Están sizeof y CHAR_BIT inexacto o he entendido mal algo fundamental?

avatar de usuario
james mcnellis

long puede ser un tipo de 64 bits, pero 1 sigue siendo un int. Necesitas hacer 1 a long int utilizando el L sufijo:

unsigned long x = 1UL << 32;

(También deberías hacerlo unsigned utilizando el U sufijo como he mostrado, para evitar los problemas de desplazamiento a la izquierda de un entero con signo. No hay problema cuando un long tiene 64 bits de ancho y cambia 32 bits, pero sería un problema si cambiara 63 bits)

  • haría unsigned long x = 1; x <<= 32; trabajo, por interés?

    – Niet el oscuro Absol

    17 de noviembre de 2010 a las 3:53

  • @Kolink: Sí, eso tendría el mismo efecto que (unsigned long)1 << 32 El operando izquierdo solo tiene que ser un unsigned long. los UL sufijo es la forma más sencilla de lograrlo.

    –James McNellis

    17 de noviembre de 2010 a las 4:03


  • @James McNellis: ¿Cuál es el problemas de izquierda desplazar un entero con signo? solo se que Correcto cambiar un entero con signo puede conducir a un resultado diferente con diferentes compiladores.

    – pynexj

    18 de marzo de 2013 a las 5:34

  • @whjm: Puede desbordarse. El desbordamiento de enteros con signo es un comportamiento indefinido.

    –Siyuan Ren

    10 de marzo de 2014 a las 9:46

  • @whjm: acabo de referirme al estándar C99 y encontré lo siguiente: El resultado de E1 << E2 es E1 posiciones de bit E2 desplazadas a la izquierda; los bits vacíos se rellenan con ceros. Si E1 tiene un tipo sin firmarel valor del resultado es E1 × 2 ** E2, módulo reducido uno más que el valor máximo representable en el tipo de resultado. Si E1 tiene un tipo con signo y un valor no negativo, y E1 × 2 ** E2 es representable en el tipo de resultadoentonces ese es el valor resultante; de lo contrario, el comportamiento no está definido.

    – pynexj

    17 de marzo de 2014 a las 5:33


avatar de usuario
tznza

unsigned long es de 32 bits o de 64 bits, que depende de su sistema. unsigned long long siempre es de 64 bits. Debes hacerlo de la siguiente manera:

unsigned long long x = 1ULL << 32

  • IOW, es el tamaño de la constante 1 lo que te está dando problemas, no x.

    – de Strangis

    2 oct 2012 a las 15:49

La solución aceptada está bien para [constant]ULL<<32 pero no es bueno para las variables existentes, por ejemplo [variable]<<32. La solución completa para variables es: ((unsigned long long)[variable]<<32). Aparte: mi opinión personal sobre esta advertencia es que, en primer lugar, es totalmente innecesaria. El compilador puede ver cuál es el tipo de datos de recepción y conoce el ancho de los parámetros de las definiciones en los encabezados o valores constantes. Creo que Apple podría hacer que el compilador clang sea un poco más inteligente de lo que es con respecto a esta advertencia.

largo sin signo x = 1UL << 31;

No mostrar el mensaje de error. Porque antes de especificar el 32, no es cierto porque solo se limita a 0-31.

avatar de usuario
vipul bagga

No puede cambiar un valor a su bit máximo

int x;         // let int be 4 bytes so max bits : 32 
x <<= 32; 

Entonces, esto genera la advertencia.

left shift count >= width of type (i.e type = int = 32 )

  • Tu redacción es incorrecta. Tú lata cambiar un 1 a la parte más significativa de su tipo, si es unsigned o si es signed y tiene INT_MIN == 1 << width - 1. esta cambiando más allá de ese bit más alto que puede causar problemas.

    – subrayado_d

    30/10/2017 a las 23:54

  • @underscore_d no, no puedes probarlo (en un tipo sin firmar). int main(){ unsigned int x = 1 << 32; unsigned int y = 32; unsigned int z = 1 << y; printf("x:%d, z: %d\n", x, z); }

    – NO A LA GUERRA CON RUSIA

    18/09/2018 a las 21:27


  • @EvanCarroll Creo que todos estamos discutiendo con propósitos cruzados sobre lo que significa “al máximo”, es decir, si “a” significa “por” y/o “máximo” significa “más significativo” … Estaba hablando en términos de cambio para los lo más significante poco, lo cual está bien. Lo que dijisteis tú y Vipul, 1 << 32 es decir 1 << sizeof(T) * CHAR_BITcaga la 1 un poco más allá de esoque es otra cosa.

    – subrayado_d

    18/09/2018 a las 21:32


  • Arreglé el error tipográfico de “byte”. ¡Y todavía no lo estás consiguiendo! Bits de indexación desde 1 en el lugar menos significativo: 1 es el primer bit menos significativo de un tipo de 32 bits (que, por cierto, unsigned int no es necesariamente). Para desplazar eso al bit más significativo, es decir, el bit 32, desplazamos a la izquierda por 31, entonces estamos en 1 + 31 = el bit 32, el más significativo. Estaba cuestionando la redacción y diciendo que al hacer esto, 1 << 31 en un tipo de 32 bits, está bien. no estoy diciendo que hacer 1 << 32

    – subrayado_d

    18/09/2018 a las 21:37


avatar de usuario
Mateusz Piotrowski

Puedes usar algo como eso:

unsigned long x = 1;
x = x << 32;

  • Tu redacción es incorrecta. Tú lata cambiar un 1 a la parte más significativa de su tipo, si es unsigned o si es signed y tiene INT_MIN == 1 << width - 1. esta cambiando más allá de ese bit más alto que puede causar problemas.

    – subrayado_d

    30/10/2017 a las 23:54

  • @underscore_d no, no puedes probarlo (en un tipo sin firmar). int main(){ unsigned int x = 1 << 32; unsigned int y = 32; unsigned int z = 1 << y; printf("x:%d, z: %d\n", x, z); }

    – NO A LA GUERRA CON RUSIA

    18/09/2018 a las 21:27


  • @EvanCarroll Creo que todos estamos discutiendo con propósitos cruzados sobre lo que significa “al máximo”, es decir, si “a” significa “por” y/o “máximo” significa “más significativo” … Estaba hablando en términos de cambio para los lo más significante poco, lo cual está bien. Lo que dijisteis tú y Vipul, 1 << 32 es decir 1 << sizeof(T) * CHAR_BITcaga la 1 un poco más allá de esoque es otra cosa.

    – subrayado_d

    18/09/2018 a las 21:32


  • Arreglé el error tipográfico de “byte”. ¡Y todavía no lo estás consiguiendo! Bits de indexación desde 1 en el lugar menos significativo: 1 es el primer bit menos significativo de un tipo de 32 bits (que, por cierto, unsigned int no es necesariamente). Para desplazar eso al bit más significativo, es decir, el bit 32, desplazamos a la izquierda por 31, entonces estamos en 1 + 31 = el bit 32, el más significativo. Estaba cuestionando la redacción y diciendo que al hacer esto, 1 << 31 en un tipo de 32 bits, está bien. no estoy diciendo que hacer 1 << 32

    – subrayado_d

    18/09/2018 a las 21:37


¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad