How do you format an unsigned long long int using printf?

870,501

Solution 1

Use the ll (el-el) long-long modifier with the u (unsigned) conversion. (Works in windows, GNU).

printf("%llu", 285212672);

Solution 2

%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

Solution 3

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.

Solution 4

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.

Solution 5

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!

Share:
870,501
andrewrk
Author by

andrewrk

open source software developer

Updated on July 18, 2022

Comments

  • andrewrk
    andrewrk almost 2 years
    #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?

  • Mark Baker
    Mark Baker over 15 years
    Or to be precise it's for GNU libc, and doesn't work with Microsoft's C runtime.
  • user2522201
    user2522201 over 15 years
    This isn't a Linux/UNIX thing, the "ll" length modifier was added to Standard C in C99, if it doesn't work in "Microsoft C" then it is because they are not standards compliant.
  • Patrick McDonald
    Patrick McDonald over 15 years
    Works in Turbo C++ on Windows
  • JustJeff
    JustJeff over 14 years
    with windows, (or at least, with the microsoft C compiler for windows) there's also %I64d, %I32u, and %I32d
  • スーパーファミコン
    スーパーファミコン over 14 years
    Works for me in VS2008. Moreover, as far as I remember the MS C Compiler (when set up to compile straight C) is supposed to be C90 compliant by design; C99 introduced some things that not everyone liked.
  • CMircea
    CMircea about 14 years
    What does it have to do with Windows 2000? The C library is the one that handles printf.
  • Adam Pierce
    Adam Pierce about 14 years
    Just what I observed. I wrote an app which used this construct and it worked perfectly on WinXP but spat garbage on Win2k. Maybe it's something to do with a system call that the C library is making to the kernel, maybe it's something to do with Unicode, who knows. I remember having to work around it using _i64tot() or something like that.
  • BD at Rivenhill
    BD at Rivenhill about 13 years
    +1 for the reference to PRIu64, which I had never seen, but this doesn't seem portable to 64 bit Linux (at least) because PRIu64 expands to "lu" instead of "llu".
  • dmitrii
    dmitrii over 12 years
    One thing to keep in mind here is that if you are passing multiple long long arguments to printf 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 cause printf to crash). Essentially, variable arguments are passed to printf without any type information, so if the format string is incorrect, the result is unpredictable.
  • Ringding
    Ringding about 12 years
    And why would that be bad? A long is a 64 bit value on 64 bit Linux, as on every other OS except for Windows.
  • ahcox
    ahcox over 11 years
    Heard Herb Sutter say in an interview that Microsoft's customers don't ask for C99 so their pure C compiler has been frozen at C90. That applies if you are compiling as C. If you compile as C++, as others have noted above, you should be fine.
  • Antarus
    Antarus almost 11 years
    everything changes with 64 bit machine
  • happy_marmoset
    happy_marmoset over 10 years
    where these PRId64, PRId32 macros defined?
  • Nathan Fellman
    Nathan Fellman over 10 years
    @happy_marmoset: they are defined in inttypes.h
  • cardiff space man
    cardiff space man about 10 years
    Using the Cygwin compiler that cross-compiles to x86_64 (x86_64-w64-mingw32-g++) %lx with a long long unsigned int gives an error that the format and type don't go together, and using %llx with the same variable and same compiler gives an error that %llx is an unknown format. And the variable is actually a pthread_t. So it doesn't "work in Windows/GNU" and the problem is not that it's Microsoft's compiler.
  • cardiff space man
    cardiff space man about 10 years
    For Hex output, an unsigned long long would be printed with %I64x. The virtually portable way is to cast the number to intmax_t and use PRIXMAX. And to use PRIXMAX or anything like it with C++ in a GNU compiler, you have to #define __STDC_FORMAT_MACROS. And in the conditions I'm describing, the definition of PRIXMAX I get appears to be the wrong one and I have to force %I64X which works.
  • phuclv
    phuclv about 10 years
    @BDatRivenhill Linux/Unix uses LP64 in which long is 64 bits
  • phuclv
    phuclv over 9 years
    however, to make it more portable, use int64_t instead because there may well be some implementations with long long larger than long
  • Lasse Kliemann
    Lasse Kliemann almost 8 years
    I think you need PRIu64 and PRIu32 for unsigned integers.
  • 0xAK
    0xAK almost 8 years
    Very nice! i was wondering how i could get it in hex representation
  • MD XF
    MD XF about 7 years
    Is inttypes.h standard? Wouldn't it be stdint.h?
  • user2316602
    user2316602 almost 7 years
    The ints are in both, inttypes also contain bools which can be found in stdbool.h
  • Seshadri R
    Seshadri R over 6 years
    But, almost all the C++ and C compilers give the warning: warning: use of 'll' length modifier with 'p' type character [-Wformat=]
  • veganaiZe
    veganaiZe almost 6 years
    The Win2k/Win9x issue is likely due to 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.
  • DevSolar
    DevSolar almost 6 years
    Note that these exact-width types are optional, as there are architectures out there that do not have integer types of those exact widths. Only the leastX and fastX types (which may actually be wider than indicated) are mandatory.
  • dyasta
    dyasta over 5 years
    Try an actual 64-bit number instead of '285212672' and I do not believe the first example runs correctly, compiled to any target.
  • Antti Haapala -- Слава Україні
    Antti Haapala -- Слава Україні over 4 years
    this utterly broken answer has doubly-undefined behaviour and does not even begin to answer the question.
  • Antti Haapala -- Слава Україні
    Antti Haapala -- Слава Україні over 4 years
    I don't have lltoa.
  • kungfooman
    kungfooman over 4 years
    @AnttiHaapala You say this answer is utterly broken with doubly-undefined behaviour, can you elaborate or shall I just delete it? Or keep it as a good bad example?
  • pmor
    pmor almost 4 years
    Why not ull instead of llu?
  • brian beuning
    brian beuning over 3 years
    UB1: all pointers are same size, sizeof(char *) == sizeof(long long *), so size modifier on %p is pointless. UB2: 0xff.fff is type int and format %p expects a pointer
  • VimNing
    VimNing over 3 years
    +l: "%llu" surprised me. I used "%ull" and got warning said I provided int.
  • chux - Reinstate Monica
    chux - Reinstate Monica over 3 years
    @Rainning "%ull" prints an unsigned and then "ll".
  • john
    john about 3 years
    Error in code blocks: error: unknown type name 'uint64_t'; did you mean 'wint_t'?|
  • Nathan Fellman
    Nathan Fellman about 3 years
    @john: no, uint64_t. I think that this is a somewhat non-standard extension, so different compilers or environments might have different names.
  • chux - Reinstate Monica
    chux - Reinstate Monica over 2 years
    Nathan Fellman, Please fix this highly upvoted answer: "PRId64" --> "PRIu64". Likewise for 32-bit.
  • chux - Reinstate Monica
    chux - Reinstate Monica over 2 years
    "%" 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.
  • chux - Reinstate Monica
    chux - Reinstate Monica over 2 years
    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.
  • chux - Reinstate Monica
    chux - Reinstate Monica over 2 years
    sizeof(num) returns a size_t. "%d" is not specifed to work with that. Better with "%zu".