Calculating and using maximum value of uint32_t

15,947

Solution 1

The portable way to print a uintN_t object is to cast it to a uintmax_t and use the j length modifier with the u conversion specifier:

printf("%ju\n", (uintmax_t)(UINT32_MAX));

The j means that the argument is either an intmax_t or a uintmax_t; the u means it is unsigned, so it is a uintmax_t.

Or, you can use the format strings defined in <inttypes.h> (n this case, you'd use PRIu32):

printf("%" PRIu32 "\n", UINT32_MAX);

You can't just use %u because it isn't guaranteed that int is represented by at least 32 bits (it only needs to be represented by at least 16 bits).

Solution 2

You encountered your specific problem because %d is a signed formatter.

There are a number of ways to fix it (two have already been suggested), but the really correct way is to use the format specifiers defined in <inttypes.h>:

uint32_t number;
printf("number is %" PRIu32 "\n", number);

Solution 3

%d is for signed integers. Use %u.

EDIT: Ignore this answer and use James's, which is more complete.

Share:
15,947
orlp
Author by

orlp

Computer Science PhD student at CWI Amsterdam. Cryptography, information theory, compression, computer graphics, low-level optimization, discrete mathematics, algorithms &amp; data structures - it all interests me! Favourite languages: Rust, Python, C++, C. Achievements: Gold C++ badge #238 Gold Python badge #236 Gold C badge #225 #1021 to reach 100,000 reputation Pattern-defeating quicksort

Updated on June 04, 2022

Comments

  • orlp
    orlp about 2 years

    I know that UINT32_MAX exists, but I haven't been able to use it. I tried printf("%d\n", UINT32_MAX); and it printed out -1. Using %ld instead of %d presented me with the error that UINT32_MAX is of the type unsigned int and needs %d to print it out.

    Please help, what I ideally want is a macro/enum that holds the maximum value of word_t which is a type defined by me which currently is uint32_t.

    I hope that I made clear what I want, if not please feel free to ask.

    EDIT

    I forgot to say what I'm actually trying to do. All of this will be used to set an array of integers all to their maximum value, because that array of integers actually is a bitmap that will set all bits to 1.

    • Steve Jessop
      Steve Jessop over 13 years
      If you want to set an unsigned integer to all-bits-1, then just assign -1 to it. The type doesn't matter (as long as it's unsigned), the representation of signed integers on the implementation doesn't matter, and you don't need to figure out the name of the macro for the correct max value (which makes it easier to deal with typedefs that might change in future).
    • orlp
      orlp over 13 years
      @Steve Jessop: Is that just accidental behaviour or can you really rely on it?
    • Steve Jessop
      Steve Jessop over 13 years
      it's guaranteed by the C standard. Signed-to-unsigned conversion is 6.3.1.3/2, and representation of unsigned int types is 6.2.6.2/1 (although actually you don't care about the storage representation, you just care that -1 is converted to unsigned by "adding one more than the maximum value that can be represented in the new type", and hence -1 converted to any unsigned type is UTYPE_MAX).
    • Hobblin
      Hobblin over 12 years
      I know it might be useless to talk about a "correct" way... but shouldn't ~0 be better than -1... I mean, ~0 is what you actually want, -1 just gives ~0 as a side-effect of addition/subtraction.
  • James McNellis
    James McNellis over 13 years
    What if int is represented by 16 bits?
  • Steve Jessop
    Steve Jessop over 13 years
    There's PRIu32 in inttypes.h, for the common case where the format string is defined in the same source code as the printf statement. If the format string is defined somewhere else that might not be compatible, then it's no good.
  • orlp
    orlp over 13 years
    Thanks a lot, doesn't really matter though, the use of this won't be the printing out, but this answer made me understood what the issue was. Accepted.
  • orlp
    orlp over 13 years
    This won't work at all, 0xFF is completely unrelated to uint32_t.
  • James McNellis
    James McNellis over 13 years
    @Steve: Interesting; I didn't know those were in there!
  • nullforce
    nullforce over 13 years
    It fills the block of memory one byte at a time with 0xFF. 4 bytes per int * arraysize.
  • Pascal Cuoq
    Pascal Cuoq over 13 years
    @James Well, I would use your answer then :)
  • Steve Jessop
    Steve Jessop over 13 years
    Provided that CHAR_BIT == 8, this is correct for uint32_t (as in the question), because uint32_t is guaranteed not to have padding bits. It's technically not portable for unsigned int, since that is permitted to have padding bits and if so this might create a trap representation. But we also know from the question that on the implementation the questioner is using, the two types are the same anyway. So +1 to counter an unjustified -1. 0xFF is related to uint32_t, assuming 8 bit bytes. With 16 bit bytes this would be wrong, so better to use -1 than 0xff.
  • Steve Jessop
    Steve Jessop over 13 years
    I mention them as someone who can never be bothered to actually use the things. Other than debugging (in which case you know the implementation), printf is UI programming. I don't do UIs in C ;-)
  • R.. GitHub STOP HELPING ICE
    R.. GitHub STOP HELPING ICE over 13 years
    @Steve: The only way uint32_t can exist is if CHAR_BIT is 8, 16, or 32. The assumption would go away if you just replace 0xFF with -1. :-)
  • u0b34a0f6ae
    u0b34a0f6ae over 12 years
    long is at least 32-bits so %lu and (unsigned long)UINT32_MAX paired together should be fine.