#include <stdio.h>
int main() {
unsigned long long int num = 285212672; //FYI: fits in 29 bits
int normalInt = 5;
printf("My number is %d bytes wide and its value is %ul. A normal number is %d.\n", sizeof(num), num, normalInt);
return 0;
}
Output:
My number is 8 bytes wide and its value is 285212672l. A normal number is 0.
I assume this unexpected result is from printing the unsigned long long int
. How do you printf()
an unsigned long long int
?
Use the ll (el-el) long-long modifier with the u (unsigned) conversion. (Works in windows, GNU).
printf("%llu", 285212672);
%d
--> for int
%u
--> for unsigned int
%ld
--> for long int
or long
%lu
--> for unsigned long int
or long unsigned int
or unsigned long
%lld
--> for long long int
or long long
%llu
--> for unsigned long long int
or unsigned long long
You may want to try using the inttypes.h library that gives you types such as int32_t
, int64_t
, uint64_t
etc. You can then use its macros such as:
uint64_t x;
uint32_t y;
printf("x: %"PRId64", y: %"PRId32"\n", x, y);
This is "guaranteed" to not give you the same trouble as long
, unsigned long long
etc, since you don't have to guess how many bits are in each data type.
PRId64
, PRId32
macros defined?
inttypes.h
PRIu64
and PRIu32
for unsigned integers.
inttypes.h
standard? Wouldn't it be stdint.h
?
leastX
and fastX
types (which may actually be wider than indicated) are mandatory.
For long long (or __int64) using MSVS, you should use %I64d:
__int64 a;
time_t b;
...
fprintf(outFile,"%I64d,%I64d\n",a,b); //I is capital i
That is because %llu doesn't work properly under Windows and %d can't handle 64 bit integers. I suggest using PRIu64 instead and you'll find it's portable to Linux as well.
Try this instead:
#include <stdio.h>
#include <inttypes.h>
int main() {
unsigned long long int num = 285212672; //FYI: fits in 29 bits
int normalInt = 5;
/* NOTE: PRIu64 is a preprocessor macro and thus should go outside the quoted string. */
printf("My number is %d bytes wide and its value is %" PRIu64 ". A normal number is %d.\n", sizeof(num), num, normalInt);
return 0;
}
Output
My number is 8 bytes wide and its value is 285212672. A normal number is 5.
int64_t
instead because there may well be some implementations with long long larger than long
"%" PRIu64
matches uint64_t
and "%llu"
matches unsigned long long
. This answer has "%" PRIu64
with unsigned long long
. This approach plants seeds for UB when unsigned long long
is more than 64-bit. Best to avoid.
In Linux it is %llu
and in Windows it is %I64u
Although I have found it doesn't work in Windows 2000, there seems to be a bug there!
unsigned long long
datatype being relatively new (at the time, with the C99 standard) but C compilers (including MinGW/GCC) utilizing the old Microsoft C runtime which only supported the C89 spec. I only have access to really old and reasonably recent Windows API docs. So it's difficult to say exactly when I64u
support was dropped in. But it sounds like the XP-era.
Compile it as x64 with VS2005:
%llu works well.
Apparently no one has come up with a multi-platform* solution for over a decade since [the] year 2008, so I shall append mine 😛. Plz upvote. (Joking. I don’t care.)
Solution: lltoa()
How to use:
#include <stdlib.h> /* lltoa() */
// ...
char dummy[255];
printf("Over 4 bytes: %s\n", lltoa(5555555555, dummy, 10));
printf("Another one: %s\n", lltoa(15555555555, dummy, 10));
OP’s example:
#include <stdio.h>
#include <stdlib.h> /* lltoa() */
int main() {
unsigned long long int num = 285212672; // fits in 29 bits
char dummy[255];
int normalInt = 5;
printf("My number is %d bytes wide and its value is %s. "
"A normal number is %d.\n",
sizeof(num), lltoa(num, dummy, 10), normalInt);
return 0;
}
Unlike the %lld
print format string, this one works for me under 32-bit GCC on Windows.
*) Well, almost multi-platform. In MSVC, you apparently need _ui64toa()
instead of lltoa()
.
lltoa
.
lltoa()
is not a standard C library function. It does not work under 32-bit GCC on Windows when compiled unless non-standard extensions are allowed.
sizeof(num)
returns a size_t
. "%d"
is not specifed to work with that. Better with "%zu"
.
How do you format an unsigned long long int using printf?
Since C99 use an "ll"
(ell-ell) before the conversion specifiers o,u,x,X
.
In addition to base 10 options in many answers, there are base 16 and base 8 options:
Choices include
unsigned long long num = 285212672;
printf("Base 10: %llu\n", num);
num += 0xFFF; // For more interesting hex/octal output.
printf("Base 16: %llX\n", num); // Use uppercase A-F
printf("Base 16: %llx\n", num); // Use lowercase a-f
printf("Base 8: %llo\n", num);
puts("or 0x,0X prefix");
printf("Base 16: %#llX %#llX\n", num, 0ull); // When non-zero, print leading 0X
printf("Base 16: %#llx %#llx\n", num, 0ull); // When non-zero, print leading 0x
printf("Base 16: 0x%llX\n", num); // My hex fave: lower case prefix, with A-F
Output
Base 10: 285212672
Base 16: 11000FFF
Base 16: 11000fff
Base 8: 2100007777
or 0x,0X prefix
Base 16: 0X11000FFF 0
Base 16: 0x11000fff 0
Base 16: 0x11000FFF
int
.
"%ull"
prints an unsigned
and then "ll"
.
In addition to what people wrote years ago:
you might get this error on gcc/mingw:
main.c:30:3: warning: unknown conversion type character 'l' in format [-Wformat=]
printf("%llu\n", k);
Then your version of mingw does not default to c99. Add this compiler flag: -std=c99
.
Non-standard things are always strange :)
for the long long portion under GNU it's L
, ll
or q
and under windows I believe it's ll
only
Well, one way is to compile it as x64 with VS2008
This runs as you would expect:
int normalInt = 5;
unsigned long long int num=285212672;
printf(
"My number is %d bytes wide and its value is %ul.
A normal number is %d \n",
sizeof(num),
num,
normalInt);
For 32 bit code, we need to use the correct __int64 format specifier %I64u. So it becomes.
int normalInt = 5;
unsigned __int64 num=285212672;
printf(
"My number is %d bytes wide and its value is %I64u.
A normal number is %d",
sizeof(num),
num, normalInt);
This code works for both 32 and 64 bit VS compiler.
Hex:
printf("64bit: %llp", 0xffffffffffffffff);
Output:
64bit: FFFFFFFFFFFFFFFF
Success story sharing
long long
arguments toprintf
and use the wrong format for one of them, say%d
instead of%lld
, then even the arguments printed after the incorrect one may be completely off (or can even causeprintf
to crash). Essentially, variable arguments are passed to printf without any type information, so if the format string is incorrect, the result is unpredictable.