gcc 7.3 Operación de enteros sin signo de 128 bits

3 minutos de lectura

avatar de usuario
melquiades

Estoy confundido con el uso de enteros de 128 bits. Por favor, mire el código de prueba:

uint128_t test_data = 0x00000000FFFFFFFF0101010101010101;
uint64_t test_data_h = test_data  >> 64;
uint64_t test_data_l = test_data ;
printf("test_data 0x %016llx %016llx\n", test_data_h, test_data_l);

espero el test_data_h para ser 0x00000000FFFFFFFF, pero el resultado es:

test data 0x 0000000000000000 0101010101010101

¿Por qué es esto?

  • Dedique un minuto a hacer el recorrido para comprender cómo funciona esta comunidad. Y si alguna respuesta le ayuda, debe hacer clic en la marca de verificación verde para aceptarla.

    – phuclv

    29 de marzo de 2020 a las 10:11

  • ¿Responde esto a tu pregunta? Asignación de enteros de 128 bits en C

    – usuario2284570

    11 de junio de 2020 a las 14:47

Muchos compiladores no admiten constantes de 128 bits.

En cambio

// uint128_t test_data = 0x00000000FFFFFFFF0101010101010101;
uint128_t test_data = (((uint128_t) 0x00000000FFFFFFFF) << 64) | 0x0101010101010101;

Sugerencia: habilite todas las advertencias del compilador.

avatar de usuario
phuclv

GCC no admite literales enteros de 128 bits

No hay soporte en GCC para expresar una constante entera de tipo __int128 para objetivos con long long entero de menos de 128 bits de ancho.

Enteros de 128 bits

Así que tendrás que construirlo a partir de partes más pequeñas. ((unsigned __int128)high << 64) | low


Si activó todas las advertencias, verá

<source>:6:35: warning: integer constant is too large for its type
    6 |     unsigned __int128 test_data = 0x00000000FFFFFFFF0101010101010101;
      |                                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Demostración en Godbolt

Debido a que el tipo de un literal entero es “el primer tipo en el que puede caber el valor, de la lista de tipos que depende de qué base numérica y qué integer-suffix se utilizó” y la lista de tipos no contiene tipos no estándar como __int128.

C99 también admite “tipos enteros extendidos” y en la misma página también puede ver que

Si el valor de la constante entera es demasiado grande para caber en cualquiera de los tipos permitidos por la combinación de sufijo/base y el compilador admite tipos enteros extendidos (como __int128), a la constante se le puede dar el tipo entero extendido; de lo contrario, el programa está mal formado.

constante entera

Desafortunadamente __int128 es no un tipo entero extendido en GCC. Puedes ver eso fácilmente intmax_t mapas a long long en vez de __int128. Por lo tanto, no puedes tener __int128 literal, a menos que el compilador tenga otra extensión, como ICC. Puede ver que no hay una advertencia de literal entero relevante de ICC en el Enlace de Godbolt arriba

¿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