Search code examples
cgcc

how to print __uint128_t number using gcc?


Is there PRIu128 that behaves similar to PRIu64 from <inttypes.h>:

printf("%" PRIu64 "\n", some_uint64_value);

Or converting manually digit by digit:

int print_uint128(uint128_t n) {
  if (n == 0)  return printf("0\n");

  char str[40] = {0}; // log10(1 << 128) + '\0'
  char *s = str + sizeof(str) - 1; // start at the end
  while (n != 0) {
    if (s == str) return -1; // never happens

    *--s = "0123456789"[n % 10]; // save last digit
    n /= 10;                     // drop it
  }
  return printf("%s\n", s);
}

is the only option?

Note that uint128_t is my own typedef for __uint128_t.


Solution

  • No there isn't support in the library for printing these types. They aren't even extended integer types in the sense of the C standard.

    Your idea for starting the printing from the back is a good one, but you could use much larger chunks. In some tests for P99 I have such a function that uses

    uint64_t const d19 = UINT64_C(10000000000000000000);
    

    as the largest power of 10 that fits into an uint64_t.

    As decimal, these big numbers get unreadable very soon so another, easier, option is to print them in hex. Then you can do something like

      uint64_t low = (uint64_t)x;
      // This is UINT64_MAX, the largest number in 64 bit
      // so the longest string that the lower half can occupy
      char buf[] = { "18446744073709551615" };
      sprintf(buf, "%" PRIX64, low);
    

    to get the lower half and then basically the same with

      uint64_t high = (x >> 64);
    

    for the upper half.