使用 %d 打印 unsigned long long [英] Printing unsigned long long using %d
问题描述
为什么我打印以下内容时得到 -1?
Why do I get -1 when I print the following?
unsigned long long int largestIntegerInC = 18446744073709551615LL;
printf ("largestIntegerInC = %d\n", largestIntegerInC);
我知道我应该使用 llu
而不是 d
,但是为什么我得到 -1 而不是 18446744073709551615LL?
I know I should use llu
instead of d
, but why do I get -1 instead of 18446744073709551615LL?
是因为溢出吗?
推荐答案
在C(99)中,LLONG_MAX
,long long int
类型的最大值保证为至少为 9223372036854775807
.unsigned long long int
的最大值保证至少为 18446744073709551615
,即 264−1 (0xffffffffffffffff
).
In C (99), LLONG_MAX
, the maximum value of long long int
type is guaranteed to be at least 9223372036854775807
. The maximum value of an unsigned long long int
is guaranteed to be at least 18446744073709551615
, which is 264−1 (0xffffffffffffffff
).
所以,初始化应该是:
unsigned long long int largestIntegerInC = 18446744073709551615ULL;
(注意 ULL
.)因为 largestIntegerInC
是 unsigned long long int
类型,你应该用正确的格式说明符打印它,这是 "%llu"
:
(Note the ULL
.) Since largestIntegerInC
is of type unsigned long long int
, you should print it with the right format specifier, which is "%llu"
:
$ cat test.c
#include <stdio.h>
int main(void)
{
unsigned long long int largestIntegerInC = 18446744073709551615ULL;
/* good */
printf("%llu\n", largestIntegerInC);
/* bad */
printf("%d\n", largestIntegerInC);
return 0;
}
$ gcc -std=c99 -pedantic test.c
test.c: In function ‘main’:
test.c:9: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘long long unsigned int’
上面的第二个printf()
是错误的,它可以打印任何东西.您正在使用 "%d"
,这意味着 printf()
需要一个 int
,但得到一个 unsigned long long int
,它(很可能)与 int
的大小不同.您得到 -1
作为输出的原因是由于(坏)运气,以及在您的机器上,数字使用二进制补码表示的事实.
The second printf()
above is wrong, it can print anything. You are using "%d"
, which means printf()
is expecting an int
, but gets a unsigned long long int
, which is (most likely) not the same size as int
. The reason you are getting -1
as your output is due to (bad) luck, and the fact that on your machine, numbers are represented using two's complement representation.
要看看这会如何糟糕,让我们运行以下程序:
To see how this can be bad, let's run the following program:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
int main(int argc, char *argv[])
{
const char *fmt;
unsigned long long int x = ULLONG_MAX;
unsigned long long int y = 42;
int i = -1;
if (argc != 2) {
fprintf(stderr, "Need format string\n");
return EXIT_FAILURE;
}
fmt = argv[1];
printf(fmt, x, y, i);
putchar('\n');
return 0;
}
在我的 Macbook 上,使用 "%d %d %d"
运行程序给我 -1 -1 42
,在 Linux 机器上,相同的程序使用相同的格式给我 -1 42 -1
.糟糕.
On my Macbook, running the program with "%d %d %d"
gives me -1 -1 42
, and on a Linux machine, the same program with the same format gives me -1 42 -1
. Oops.
事实上,如果你想在你的 largestIntegerInC
变量中存储最大的 unsigned long long int
数字,你应该包括 limits.h
并使用 ULLONG_MAX
.或者您应该将 assing -1
存储到您的变量中:
In fact, if you are trying to store the largest unsigned long long int
number in your largestIntegerInC
variable, you should include limits.h
and use ULLONG_MAX
. Or you should store assing -1
to your variable:
#include <limits.h>
#include <stdio.h>
int main(void)
{
unsigned long long int largestIntegerInC = ULLONG_MAX;
unsigned long long int next = -1;
if (next == largestIntegerInC) puts("OK");
return 0;
}
在上面的程序中,largestIntegerInC
和 next
都包含 unsigned long long int
类型的最大可能值.
In the above program, both largestIntegerInC
and next
contain the largest possible value for unsigned long long int
type.
这篇关于使用 %d 打印 unsigned long long的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!