打印 unsigned long long int 值类型返回奇怪的结果 [英] Printing unsigned long long int Value Type Returns Strange Results

查看:157
本文介绍了打印 unsigned long long int 值类型返回奇怪的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用 printf 函数打印 unsigned long long int

类型的值时遇到问题

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

<小时>

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

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

返回:

<块引用>

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

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

<小时>

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

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

返回:

<块引用>

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

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

<小时>

还尝试了两个 ULONG_MAX

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

返回:

<块引用>

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

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

<小时>

为什么会这样?能给我解释一下吗?

解决方案

这是错误的:

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

您使用了 unsigned long long 格式说明符,但是您传递了一个 int 和一个 unsigned long 值.促销规则意味着您可以对 int 大小或更小的所有内容草率,这适用于 long long.

使用强制转换:

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

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

所以longlong long一定要小心,intshort可以马虎> 和 char.

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

<前>test.c:5:警告:格式%llu"需要类型long long unsigned int",但参数 2 的类型为int"test.c:5:警告:格式%llu"需要类型long long unsigned int",但参数 3 的类型为long unsigned int"

I have a problem while using the printf function to print values of type 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...


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

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 0 (Visual Studio)


Then I tried to using printf to print two zeros

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 to 0 (Visual Studio)


Also tried two ULONG_MAX values

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 0 (Visual Studio)


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

解决方案

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.

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.

So you must be careful with long and long long, but you can be sloppy with int, short, and 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:

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’

这篇关于打印 unsigned long long int 值类型返回奇怪的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆