How to print __int128 in g++?
I would recommend against overloading operator<<
for __int128_t
. The reason is that whenever you see cout << x
for some integer type, you'd expect that all kinds of manipulators like std::hex
or std::setw
should also work. The most important guideline when overloading operators is: "do as the ints do".
As an alternative, I would recommend using a decimal_string(__int128_t)
function that you can use as cout << decimal_string(x);
in your code. For the string conversion, you can use the algorithm from any of the C-related Q&As. This makes it clear that you have special code for your 128-bit ints. Whenever the Standard Library upgrades to 128-bit support, you can drop it (and it's easy to grep
for these functions).
If you don't need any of the fancy formatting options, writing
your own <<
operator is trivial. Formally, I suspect that
writing one for __int128_t
would be considered undefined
behavior, but practically, I think it would work, up until the
library starts providing actual support for it (at which point,
you'd retire your conversion operator).
Anyway, something like the following should work:
std::ostream&
operator<<( std::ostream& dest, __int128_t value )
{
std::ostream::sentry s( dest );
if ( s ) {
__uint128_t tmp = value < 0 ? -value : value;
char buffer[ 128 ];
char* d = std::end( buffer );
do
{
-- d;
*d = "0123456789"[ tmp % 10 ];
tmp /= 10;
} while ( tmp != 0 );
if ( value < 0 ) {
-- d;
*d = '-';
}
int len = std::end( buffer ) - d;
if ( dest.rdbuf()->sputn( d, len ) != len ) {
dest.setstate( std::ios_base::badbit );
}
}
return dest;
}
Note that this is just a quicky, temporary fix, until the time
the g++ library supports the type. It counts on 2's complement,
wrap around on overflow, for __int128_t
, but I'd be very
surprised if that wasn't the case (formally, it's undefined
behavior). If not, you'll need to fix up the initialization of
tmp
. And of course, it doesn't handle any of the formatting
options; you can add as desired. (Handling padding and the
adjustfield
correctly can be non-trivial.)