【问题标题】:How to convert from boost::multiprecision::cpp_int to cpp_dec_float<0> (rather than to cpp_dec_float_50, etc.)?如何从 boost::multiprecision::cpp_int 转换为 cpp_dec_float<0> (而不是转换为 cpp_dec_float_50 等)?
【发布时间】:2014-04-12 17:25:11
【问题描述】:

正如Boost Multiprecision library 文档中所述,从boost::multiprecision::cpp_int 转换为boost::multiprecision::cpp_dec_float 很简单:

// Some interconversions between number types are completely generic,
// and are always available, albeit the conversions are always explicit:

cpp_int cppi(2);
cpp_dec_float_50 df(cppi);    // OK, int to float // <-- But fails with cpp_dec_float<0>!

cpp_int 转换为定宽浮点类型(即cpp_dec_float_50)的能力让人希望可以将cpp_int 转换为任意类型-width 库中的浮点类型 - 即 cpp_dec_float&lt;0&gt;。但是,这不起作用;我在 Visual Studio 2013 中的转换失败,如下面的简单示例程序所示:

#include <boost/multiprecision/number.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>

int main()
{
    boost::multiprecision::cpp_int n{ 0 };
    boost::multiprecision::cpp_dec_float<0> f{ n }; // Compile error in MSVC 2013
}

确实按预期成功转换为cpp_dec_float_50,但如前所述,我希望转换为任意精度的浮点类型:cpp_dec_float&lt;0&gt;

错误出现在文件&lt;boost/multiprecision/detail/default_ops.hpp&gt;中内部Boost Multiprecision代码的以下代码sn-p中:

template <class R, class T>
inline bool check_in_range(const T& t)
{
   // Can t fit in an R?
   if(std::numeric_limits<R>::is_specialized && std::numeric_limits<R>::is_bounded
      && (t > (std::numeric_limits<R>::max)()))
      return true;
   return false;
}

错误信息是:

错误 C2784: 'enable_if::result_type,detail::expression::result_type>,bool>::type boost::multiprecision::operator >(const boost::multiprecision::detail::expression &,常量 boost::multiprecision::detail::expression &)' : 无法推断出“const”的模板参数 boost::multiprecision::detail::expression &' 来自'const next_type'

是否可以将boost::multiprecision::cpp_int 转换为boost::multiprecision::cpp_dec_float&lt;0&gt;(而不是转换为具有固定小数精度的浮点类型,如cpp_dec_float_50)?

(请注意,在我的程序中,任何时候都只实例化一个浮点数实例,并且不经常更新,所以我可以让这个实例占用大量内存并花费很长时间支持非常庞大的数字。)

谢谢!

【问题讨论】:

    标签: c++ c++11 boost multiprecision


    【解决方案1】:

    我对 Boost Multiprecision 没有太多经验,但在我看来模板类 cpp_dec_float&lt;&gt; 就是他们所说的后端,你需要将它包装在 @987654324 中@adapter 以便将其用作算术类型。

    这是我的看法:Live On Coliru

    #include <boost/multiprecision/number.hpp>
    #include <boost/multiprecision/cpp_int.hpp>
    #include <boost/multiprecision/cpp_dec_float.hpp>
    #include <iostream>
    
    namespace mp = boost::multiprecision;
    
    int main()
    {
        using Int = mp::cpp_int;
    
        // let's think of a nice large number
        Int n = 1;
        for (Int f = 42; f>0; --f)
            n *= f;
    
        std::cout << n << "\n\n"; // print it for vanity 
    
        // let's convert it to cpp_dec_float
        // and... do something with it
        using Dec = mp::number<mp::cpp_dec_float<0> >;
        std::cout << n.convert_to<Dec>();
    }
    

    输出:

    1405006117752879898543142606244511569936384000000000
    
    1.40501e+51
    

    如果convert_to&lt;&gt; 被允许,那么显式转换构造函数 也会起作用,我希望:

    Dec decfloat(n);
    

    【讨论】:

    • 太棒了!我可能会在明天尝试一下,让您知道它是否也适合我。
    • @Gracchus 它不会截断?精度完全保真。默认情况下,只是屏幕表示不是。为什么?好吧,因为在页面上运行的数字很少有用。人们很难阅读超过 30 位的数字……那么,如果您需要全精度序列化,请使用 Boost 序列化?
    • @Gracchus 我刚刚在rounding question 上完成了答案。我之前时间有点短,对图书馆感到困惑:/让我看一下关于演示问题的问题。
    猜你喜欢
    • 2019-12-14
    • 1970-01-01
    • 1970-01-01
    • 2013-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多