Printing unsigned long long int Value Type Returns Strange Results

泪湿孤枕 提交于 2019-12-19 05:23:20

问题


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?


回答1:


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’



回答2:


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.

Try this instead:

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



回答3:


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

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

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.




回答4:


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.



来源:https://stackoverflow.com/questions/10664109/printing-unsigned-long-long-int-value-type-returns-strange-results

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!