打印unsigned long long int值类型返回奇怪的结果

时间:2022-03-07 16:45:26

I have a problem while using the printf function to print values of type unsigned long long int

我在使用printf函数打印unsigned long long int类型的值时遇到问题

I have no idea what's wrong. I'm using Dev-Cpp 4.9.9.2 and Visual Studio 2010 Professional (I know that it's not C compiler, but anyway, wanted to try) on Windows 7 Professional 64-bit. For displaying, I used %llu modifier (according to How do you printf an unsigned long long int(the format specifier for unsigned long long int)?) but I also tried I64d with no effect...

我不知道出了什么问题。我在Windows 7 Professional 64位上使用Dev-Cpp 4.9.9.2和Visual Studio 2010 Professional(我知道它不是C编译器,但无论如何,想要尝试)。为了显示,我使用了%llu修饰符(根据你如何printf一个unsigned long long int(unsigned long long int的格式说明符)?)但我也试过I64d没有效果......


Firstly, I just wanted to print minimum and maximum value of unsigned long long int (using ULONG_MAX from limits.h)

首先,我只想打印unsigned long long int的最小值和最大值(使用limits.h中的ULONG_MAX)

printf("unsigned long long int: \n%llu to %llu \n\n", 0, ULONG_MAX);

Returns:

unsigned long long int: 18446744069414584320 to 1580552164021 (Dev-Cpp)

unsigned long long int:18446744069414584320 to 1580552164021(Dev-Cpp)

unsigned long long int: 18446744069414584320 to 0 (Visual Studio)

unsigned long long int:18446744069414584320 to 0(Visual Studio)


Then I tried to using printf to print two zeros

然后我尝试使用printf打印两个零

printf("unsigned long long int: \n%llu to %llu \n\n", 0, 0);

Returns:

unsigned long long int: 0 to 1580552164021 (Dev-Cpp)

unsigned long long int:0到1580552164021(Dev-Cpp)

unsigned long long int: 0 to 0 (Visual Studio)

unsigned long long int:0到0(Visual Studio)


Also tried two ULONG_MAX values

还尝试了两个ULONG_MAX值

printf("unsigned long long int: \n%llu to %llu \n\n", ULONG_MAX, ULONG_MAX);

Returns:

unsigned long long int: 18446744073709551615 to 1580552164021 (Dev-Cpp)

unsigned long long int:18446744073709551615 to 1580552164021(Dev-Cpp)

unsigned long long int: 18446744073709551615 to 0 (Visual Studio)

unsigned long long int:18446744073709551615 to 0(Visual Studio)


Why does it behave like that? Could you explain it to me?

为什么它表现得那样?你能解释一下吗?

4 个解决方案

#1


11  

This is wrong:

这是错的:

printf("unsigned long long int: \n%llu to %llu \n\n", 0, ULONG_MAX);

You use a unsigned long long format specifier, but you pass an int and an unsigned long value. Promotion rules mean you can be sloppy for everything int-sized or smaller, which does not apply to long long.

您使用无符号长long格式说明符,但传递int和unsigned long值。促销规则意味着您可以对大小或更小的所有内容草率,这不适用于长期。

Use casts:

printf("unsigned long long int: \n%llu to %llu \n\n",
       0ULL, (unsigned long long) ULONG_MAX);

Explanation: When passing arguments to printf, any type that can fit in an int is promoted to int, and then any type that can fit in an unsigned int is promoted to unsigned int. It is also okay to pass an unsigned type to a signed format specifier or vice versa as long as the value passed can be represented using the type specified by the format specifier.

说明:将参数传递给printf时,任何可以放入int的类型都会提升为int,然后任何可以放入unsigned int的类型都会提升为unsigned int。只要传递的值可以使用格式说明符指定的类型表示,也可以将无符号类型传递给带符号的格式说明符,反之亦然。

So you must be careful with long and long long, but you can be sloppy with int, short, and char.

所以你必须小心长期和长期,但你可以用int,short和char邋。

Most compilers have settings to make them warn you about this type of error, since it can be detected at compile-time fairly easily; GCC and Clang have -Wformat which results in the following warnings:

大多数编译器都有设置让他们警告你这类错误,因为它可以很容易地在编译时检测到; GCC和Clang有-Wformat导致以下警告:

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’

#2


10  

You are not passing unsigned long longs. You are passing an int (0) and unsigned long (ULONG_MAX). You must pass to printf() exactly what you promise to pass in the format string.

你没有传递未签名的长多头。您传递的是int(0)和unsigned long(ULONG_MAX)。您必须准确传递printf()您希望传递的格式字符串。

Try this instead:

试试这个:

printf("unsigned long long int: \n%llu to %llu \n\n", 0ULL, (unsigned long long)ULONG_MAX);

#3


4  

ULONG_MAX refers to unsigned long and not to unsigned long long. For the latter, use ULLONG_MAX (note the extra L).

ULONG_MAX指的是unsigned long而不是unsigned long long。对于后者,使用ULLONG_MAX(注意额外的L)。

You need to change the printf() calls like so:

您需要更改printf()调用,如下所示:

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);

This ensures that the arguments to printf() match the format specifiers.

这可以确保printf()的参数与格式说明符匹配。

#4


0  

long long int is a type from the C99 standard, MSVC doesn't support this. Take a compiler with C99 support (like MinGW for Windows) and it will work.

long long int是C99标准的类型,MSVC不支持此。使用支持C99的编译器(如MinGW for Windows),它将工作。

#1


11  

This is wrong:

这是错的:

printf("unsigned long long int: \n%llu to %llu \n\n", 0, ULONG_MAX);

You use a unsigned long long format specifier, but you pass an int and an unsigned long value. Promotion rules mean you can be sloppy for everything int-sized or smaller, which does not apply to long long.

您使用无符号长long格式说明符,但传递int和unsigned long值。促销规则意味着您可以对大小或更小的所有内容草率,这不适用于长期。

Use casts:

printf("unsigned long long int: \n%llu to %llu \n\n",
       0ULL, (unsigned long long) ULONG_MAX);

Explanation: When passing arguments to printf, any type that can fit in an int is promoted to int, and then any type that can fit in an unsigned int is promoted to unsigned int. It is also okay to pass an unsigned type to a signed format specifier or vice versa as long as the value passed can be represented using the type specified by the format specifier.

说明:将参数传递给printf时,任何可以放入int的类型都会提升为int,然后任何可以放入unsigned int的类型都会提升为unsigned int。只要传递的值可以使用格式说明符指定的类型表示,也可以将无符号类型传递给带符号的格式说明符,反之亦然。

So you must be careful with long and long long, but you can be sloppy with int, short, and char.

所以你必须小心长期和长期,但你可以用int,short和char邋。

Most compilers have settings to make them warn you about this type of error, since it can be detected at compile-time fairly easily; GCC and Clang have -Wformat which results in the following warnings:

大多数编译器都有设置让他们警告你这类错误,因为它可以很容易地在编译时检测到; GCC和Clang有-Wformat导致以下警告:

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’

#2


10  

You are not passing unsigned long longs. You are passing an int (0) and unsigned long (ULONG_MAX). You must pass to printf() exactly what you promise to pass in the format string.

你没有传递未签名的长多头。您传递的是int(0)和unsigned long(ULONG_MAX)。您必须准确传递printf()您希望传递的格式字符串。

Try this instead:

试试这个:

printf("unsigned long long int: \n%llu to %llu \n\n", 0ULL, (unsigned long long)ULONG_MAX);

#3


4  

ULONG_MAX refers to unsigned long and not to unsigned long long. For the latter, use ULLONG_MAX (note the extra L).

ULONG_MAX指的是unsigned long而不是unsigned long long。对于后者,使用ULLONG_MAX(注意额外的L)。

You need to change the printf() calls like so:

您需要更改printf()调用,如下所示:

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);

This ensures that the arguments to printf() match the format specifiers.

这可以确保printf()的参数与格式说明符匹配。

#4


0  

long long int is a type from the C99 standard, MSVC doesn't support this. Take a compiler with C99 support (like MinGW for Windows) and it will work.

long long int是C99标准的类型,MSVC不支持此。使用支持C99的编译器(如MinGW for Windows),它将工作。