Estoy probando este código en el compilador C ++ de GNU y no puedo entender su comportamiento:
#include <stdio.h>;
int main()
{
int num1 = 1000000000;
long num2 = 1000000000;
long long num3;
//num3 = 100000000000;
long long num4 = ~0;
printf("%u %u %u", sizeof(num1), sizeof(num2), sizeof(num3));
printf("%d %ld %lld %llu", num1, num2, num3, num4);
return 0;
}
Cuando elimino el comentario de la línea comentada, el código no se compila y da un error:
error: la constante entera es demasiado grande para el tipo largo
Pero, si el código se compila como está y se ejecuta, produce valores mucho mayores que 10000000000.
¿Por qué?
c++
types
long-integer
sud03r
fuente
fuente
<stdint.h>
y utilicenuint64_t
. Para mostrar un valor de 64 bits,printf( "%" PRIu64 "\n", val);
<stdint.h>
incluido,uint64_t a = 0xffffffffffffff; printf( "%" PRIu64 "\n",a ); : error: expected ‘)’ before ‘PRIu64’ printf( "%" PRIu64 "\n",a ); :: warning: spurious trailing ‘%’ in format [-Wformat=] printf( "%" PRIu64 "\n",a );
Respuestas:
Las letras 100000000000 forman una constante entera literal, pero el valor es demasiado grande para el tipo
int
. Debe usar un sufijo para cambiar el tipo de literal, es decirlong long num3 = 100000000000LL;
El sufijo
LL
convierte el literal en tipolong long
. C no es lo suficientemente "inteligente" para concluir esto a partir del tipo de la izquierda, el tipo es una propiedad del literal en sí, no del contexto en el que se utiliza.fuente
int
,long int
ylong long int
en el que su valor puede ser representado. [C ++ §2.14.2 / 2] Por lo tanto, ahora no es necesario agregar el sufijo 'LL' en un literal entero que es demasiado grande para otros tipos.Tratar:
num3 = 100000000000LL;
Y por cierto, en C ++ esta es una extensión del compilador, el estándar no define long long, eso es parte de C99.
fuente
Depende del modo que esté compilando. long long no forma parte del estándar C ++, pero solo (normalmente) se admite como extensión. Esto afecta el tipo de literales. Los literales enteros decimales sin ningún sufijo son siempre de tipo int si int es lo suficientemente grande para representar el número, long de lo contrario. Si el número es incluso demasiado grande durante mucho tiempo, el resultado está definido por la implementación (probablemente solo un número de tipo long int que se ha truncado por compatibilidad con versiones anteriores). En este caso, debe usar explícitamente el sufijo LL para habilitar la extensión long long (en la mayoría de los compiladores).
La próxima versión de C ++ admitirá oficialmente long long de una manera que no necesitará ningún sufijo a menos que desee explícitamente que forzar el tipo de literal sea al menos long long. Si el número no se puede representar en long, el compilador automáticamente intentará utilizar long long incluso sin el sufijo LL. Creo que este también es el comportamiento de C99.
fuente
su código se compila aquí bien (incluso con esa línea sin comentar. Tuve que cambiarlo a
num3 = 100000000000000000000;
para empezar a recibir la advertencia.
fuente
long
en línea con la ABI LP64 de ese sistema operativo.