如何在G ++中打印__int128? [英] How to print __int128 in g++?

查看:105
本文介绍了如何在G ++中打印__int128?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在C ++程序中使用GCC内置类型 __ int128 进行一些操作,没有什么真正的意义,至少不足以证明仅使用BigInt库是合理的

I am using the GCC built-in type __int128 for a few things in my C++ program, nothing really significant, at least not enough to justify to use BigInt library only for that and, yet, enough to prevent to remove it totally.

我的问题是当我进入班级的印刷部分时,这是一个最小的例子:

My problem comes when I run into the printing parts my classes, here is a minimal example:

#include <iostream>

int main()
{
  __int128 t = 1234567890;

  std::cout << t << std::endl;

  return t;
}

注释 std :: cout 行会使此代码与 g ++ 很好地编译,但是拥有它会导致以下错误消息:

Commenting out the std::cout line will make this code to compile nicely with g++, but having it will cause the following error message:

int128.c: In function ‘int main()’:
int128.c:7:13: error: ambiguous overload for ‘operator<<’ (operand types are ‘std::ostream {aka std::basic_ostream<char>}’ and ‘__int128’)
   std::cout << t << std::endl;
             ^
int128.c:7:13: note: candidates are:
In file included from /usr/include/c++/4.9/iostream:39:0,
                 from int128.c:1:
/usr/include/c++/4.9/ostream:108:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostream<_CharT, _Traits>::__ostream_type& (*)(std::basic_ostream<_CharT, _Traits>::__ostream_type&)) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>] <near match>
       operator<<(__ostream_type& (*__pf)(__ostream_type&))
       ^
/usr/include/c++/4.9/ostream:108:7: note:   no known conversion for argument 1 from ‘__int128’ to ‘std::basic_ostream<char>::__ostream_type& (*)(std::basic_ostream<char>::__ostream_type&) {aka std::basic_ostream<char>& (*)(std::basic_ostream<char>&)}’
/usr/include/c++/4.9/ostream:117:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostream<_CharT, _Traits>::__ios_type& (*)(std::basic_ostream<_CharT, _Traits>::__ios_type&)) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>; std::basic_ostream<_CharT, _Traits>::__ios_type = std::basic_ios<char>] <near match>
       operator<<(__ios_type& (*__pf)(__ios_type&))
       ^
/usr/include/c++/4.9/ostream:117:7: note:   no known conversion for argument 1 from ‘__int128’ to ‘std::basic_ostream<char>::__ios_type& (*)(std::basic_ostream<char>::__ios_type&) {aka std::basic_ios<char>& (*)(std::basic_ios<char>&)}’
/usr/include/c++/4.9/ostream:127:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(std::ios_base& (*)(std::ios_base&)) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>] <near match>
       operator<<(ios_base& (*__pf) (ios_base&))
       ^
/usr/include/c++/4.9/ostream:127:7: note:   no known conversion for argument 1 from ‘__int128’ to ‘std::ios_base& (*)(std::ios_base&)’
/usr/include/c++/4.9/ostream:166:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long int) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
       operator<<(long __n)
       ^
/usr/include/c++/4.9/ostream:170:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long unsigned int) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
       operator<<(unsigned long __n)
       ^
/usr/include/c++/4.9/ostream:174:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(bool) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
       operator<<(bool __n)
       ^
In file included from /usr/include/c++/4.9/ostream:609:0,
                 from /usr/include/c++/4.9/iostream:39,
                 from int128.c:1:
/usr/include/c++/4.9/bits/ostream.tcc:91:5: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(short int) [with _CharT = char; _Traits = std::char_traits<char>]
     basic_ostream<_CharT, _Traits>::
     ^
In file included from /usr/include/c++/4.9/iostream:39:0,
                 from int128.c:1:
/usr/include/c++/4.9/ostream:181:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(short unsigned int) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
       operator<<(unsigned short __n)
       ^
In file included from /usr/include/c++/4.9/ostream:609:0,
                 from /usr/include/c++/4.9/iostream:39,
                 from int128.c:1:
/usr/include/c++/4.9/bits/ostream.tcc:105:5: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(int) [with _CharT = char; _Traits = std::char_traits<char>]
     basic_ostream<_CharT, _Traits>::
     ^
In file included from /usr/include/c++/4.9/iostream:39:0,
                 from int128.c:1:
/usr/include/c++/4.9/ostream:192:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(unsigned int) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
       operator<<(unsigned int __n)
       ^
/usr/include/c++/4.9/ostream:201:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long long int) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
       operator<<(long long __n)
       ^
/usr/include/c++/4.9/ostream:205:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long long unsigned int) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
       operator<<(unsigned long long __n)
       ^
/usr/include/c++/4.9/ostream:220:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(double) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
       operator<<(double __f)
       ^
/usr/include/c++/4.9/ostream:224:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(float) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
       operator<<(float __f)
       ^
/usr/include/c++/4.9/ostream:232:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long double) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
       operator<<(long double __f)
       ^
/usr/include/c++/4.9/ostream:245:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(const void*) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>] <near match>
       operator<<(const void* __p)
       ^
/usr/include/c++/4.9/ostream:245:7: note:   no known conversion for argument 1 from ‘__int128’ to ‘const void*’
In file included from /usr/include/c++/4.9/ostream:609:0,
                 from /usr/include/c++/4.9/iostream:39,
                 from int128.c:1:
/usr/include/c++/4.9/bits/ostream.tcc:119:5: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostream<_CharT, _Traits>::__streambuf_type*) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_ostream<_CharT, _Traits>::__streambuf_type = std::basic_streambuf<char>] <near match>
     basic_ostream<_CharT, _Traits>::
     ^
/usr/include/c++/4.9/bits/ostream.tcc:119:5: note:   no known conversion for argument 1 from ‘__int128’ to ‘std::basic_ostream<char>::__streambuf_type* {aka std::basic_streambuf<char>*}’
In file included from /usr/include/c++/4.9/iostream:39:0,
                 from int128.c:1:
/usr/include/c++/4.9/ostream:493:5: note: std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, unsigned char) [with _Traits = std::char_traits<char>]
     operator<<(basic_ostream<char, _Traits>& __out, unsigned char __c)
     ^
/usr/include/c++/4.9/ostream:488:5: note: std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, signed char) [with _Traits = std::char_traits<char>]
     operator<<(basic_ostream<char, _Traits>& __out, signed char __c)
     ^
/usr/include/c++/4.9/ostream:482:5: note: std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, char) [with _Traits = std::char_traits<char>]
     operator<<(basic_ostream<char, _Traits>& __out, char __c)
     ^
/usr/include/c++/4.9/ostream:476:5: note: std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&, char) [with _CharT = char; _Traits = std::char_traits<char>]
     operator<<(basic_ostream<_CharT, _Traits>& __out, char __c)
     ^

是的,我知道,很多行会解释 __ int128 只是没有正确处理...

Yes, I know, a lot of lines to explain that __int128 is just not properly handled...

是否有一种简单方法来获取 __ int128 并由<$打印c $ c> iostream 和其他任何数字类型一样?

Is there a simple way to get __int128 to be printed by the iostream as any other numeric types ?

编辑:对于那些仍然使C和C ++感到困惑的人,我读了问题:如何使用gcc打印__uint128_t数字?

For those who are still confusing C and C++, yes, I read the question: how to print __uint128_t number using gcc? But, this was for C and not for C++ as I am asking now.

推荐答案

如果您不需要任何精美的格式,这是C语言,而不是C ++语言。选项,用自己的<< 运算符编写
是微不足道的。正式地,我怀疑
__ int128_t 写一个将被认为是未定义的
行为,但实际上,我认为它会起作用,直到
库开始为其提供实际支持(此时,您将退休转换运营商
)。

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;
}

请注意,这只是快速,临时的解决方法,直到
g ++库支持该类型。它依靠2的补数,
在溢出时回绕,为 __ int128_t ,但是如果不是这种情况,我会非常惊讶
(形式上,这是未定义的
行为)。如果没有,则需要修复
tmp 的初始化。当然,它不处理格式为
any ;您可以根据需要添加。 (正确处理填充和
adjustfield 可能并不重要。)

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

这篇关于如何在G ++中打印__int128?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆