c - Imprimir unsigned long long int Tipo de valor devuelve resultados extraños
printf java (4)
Esto está mal:
printf("unsigned long long int: /n%llu to %llu /n/n", 0, ULONG_MAX);
Utiliza un especificador de formato unsigned long long
, pero int
un valor int
y un valor unsigned long
. Las reglas de promoción significan que puede ser descuidado para todo lo int
-sized o más pequeño, lo que no se aplica a long long
.
Usar moldes:
printf("unsigned long long int: /n%llu to %llu /n/n",
0ULL, (unsigned long long) ULONG_MAX);
Explicación: Al pasar argumentos a printf
, cualquier tipo que pueda caber en un int
se promueve a int
, y luego cualquier tipo que pueda caber en un unsigned int
se promueve a unsigned int
. También está bien pasar un tipo sin signo a un especificador de formato con signo o viceversa, siempre que el valor pasado pueda representarse utilizando el tipo especificado por el especificador de formato.
Así que debes tener cuidado con long
, pero puedes ser descuidado con int
, short
y char
.
La mayoría de los compiladores tienen configuraciones para advertirles sobre este tipo de error, ya que se puede detectar en tiempo de compilación con bastante facilidad; GCC y Clang tienen -Wformat
que da como resultado las siguientes advertencias:
test.c:5: warning: format ‘%llu’ expects type ‘long long unsigned int’, but argument 2 has type ‘int’ test.c:5: warning: format ‘%llu’ expects type ‘long long unsigned int’, but argument 3 has type ‘long unsigned int’
Tengo un problema al usar la función printf
para imprimir valores de tipo unsigned long long int
No tengo idea de lo que está mal. Estoy usando Dev-Cpp 4.9.9.2 y Visual Studio 2010 Professional (sé que no es un compilador de C, pero de todos modos, quería probar) en Windows 7 Professional de 64 bits. Para mostrar, %llu
modificador de %llu
(de acuerdo con ¿Cómo se %llu
un int largo sin signo (el especificador de formato para unsigned long long int)? ) Pero también probé I64d sin ningún efecto ...
En primer lugar, solo quería imprimir el valor mínimo y máximo de unsigned long long int
(usando ULONG_MAX
desde limits.h
)
printf("unsigned long long int: /n%llu to %llu /n/n", 0, ULONG_MAX);
Devoluciones:
unsigned long long int: 18446744069414584320 a 1580552164021 (Dev-Cpp)
unsigned long long int: 18446744069414584320 a 0 (Visual Studio)
Luego traté de usar printf
para imprimir dos ceros
printf("unsigned long long int: /n%llu to %llu /n/n", 0, 0);
Devoluciones:
unsigned long long int: 0 a 1580552164021 (Dev-Cpp)
unsigned long long int: 0 a 0 (Visual Studio)
También probé dos valores ULONG_MAX
printf("unsigned long long int: /n%llu to %llu /n/n", ULONG_MAX, ULONG_MAX);
Devoluciones:
unsigned long long int: 18446744073709551615 a 1580552164021 (Dev-Cpp)
unsigned long long int: 18446744073709551615 a 0 (Visual Studio)
¿Por qué se comporta así? ¿Podrías explicarme eso?
No estás pasando unsigned long longs
. Está pasando un int
(0) y unsigned long
(ULONG_MAX). Debe pasar a printf()
exactamente lo que promete pasar en la cadena de formato.
Pruebe esto en su lugar:
printf("unsigned long long int: /n%llu to %llu /n/n", 0ULL, (unsigned long long)ULONG_MAX);
long long int es un tipo del estándar C99, MSVC no es compatible con esto. Tome un compilador con soporte C99 (como MinGW para Windows) y funcionará.
ULONG_MAX
refiere a unsigned long
y no unsigned long long
. Para este último, use ULLONG_MAX
(tenga en cuenta el L
extra).
Necesita cambiar las llamadas a printf()
manera:
printf("unsigned long long int: /n%llu to %llu /n/n", 0ULL, ULLONG_MAX);
printf("unsigned long long int: /n%llu to %llu /n/n", ULLONG_MAX, ULLONG_MAX);
Esto asegura que los argumentos para printf()
coincidan con los especificadores de formato.