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
.
Based on sebastian's answer, this is for signed int128 in g++, not thread safe.
Here's a modified version of Leffler's answer that supports from 0 to UINT128_MAX
And try this:
I think your
print_uint128
function is awfully complex.Isn't this one simpler to write and run?
The GCC 4.7.1 manual says:
Interestingly, although that does not mention
__uint128_t
, that type is accepted, even with stringent warnings set:Compilation:
(This is with a home-compiled GCC 4.7.1 on Mac OS X 10.7.4.)
Change the constant to
0x12345678900987654321
and the compiler says:So, it isn't easy manipulating these creatures. The outputs with the decimal constant and hex constants are:
For printing in decimal, your best bet is to see if the value is larger than UINT64_MAX; if it is, then you divide by the largest power of 10 that is smaller than UINT64_MAX, print that number (and you might need to repeat the process a second time), then print the residue modulo the largest power of 10 that is smaller than UINT64_MAX, remembering to pad with leading zeroes.
This leads to something like:
The output from that is:
We can verify using
bc
:Clearly, for hex, the process is simpler; you can shift and mask and print in just two operations. For octal, since 64 is not a multiple of 3, you have to go through analogous steps to the decimal operation.
The
print_u128_u()
interface is not ideal, but it does at least return the number of characters printed, just asprintf()
does. Adapting the code to format the result into a string buffer is a not wholly trivial exercise in programming, but not dreadfully difficult.C++ variant. You may use it as a template to derive specialized C-version of the function: