How to print __int128 in g++?

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.)

Leave a Comment