How to convert from boost::multiprecision::cpp_int to cpp_dec_float<0> (rather than to cpp_dec_float_50, etc.)?

匿名 (未验证) 提交于 2019-12-03 08:54:24

问题:

As is made clear in the Boost Multiprecision library documentation, it is straightforward to convert from a boost::multiprecision::cpp_int to a 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>! 

The ability to convert from a cpp_int to a fixed-width floating-point type (i.e., a cpp_dec_float_50) gives one hope that it might be possible to convert from a cpp_int to an arbitrary-width floating-point type in the library - i.e., a cpp_dec_float<0>. However, this doesn't work; the conversion fails for me in Visual Studio 2013, as the following simple example program demonstrates:

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

It does succeed to convert to cpp_dec_float_50, as expected, but as noted, I am hoping to convert to an arbitrary precision floating point type: cpp_dec_float<0>.

The error appear in the following snippet of code from the internal Boost Multiprecision code, in the file <boost/multiprecision/detail/default_ops.hpp>:

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

The error message is:

error C2784: 'enable_if::result_type,detail::expression::result_type>,bool>::type boost::multiprecision::operator >(const boost::multiprecision::detail::expression &,const boost::multiprecision::detail::expression &)' : could not deduce template argument for 'const boost::multiprecision::detail::expression &' from 'const next_type'

Might it be possible to convert a boost::multiprecision::cpp_int to a boost::multiprecision::cpp_dec_float<0> (rather than converting to a floating-point type with a fixed decimal precision, as in cpp_dec_float_50)?

(Note that in my program, only one instance of the floating-point number is instantiated at any time, and it is updated infrequently, so I am fine with having this one instance take up lots of memory and take a long time to support really huge numbers.)

Thanks!

回答1:

I don't have much experience with Boost Multiprecision, but it seems to me that the template class cpp_dec_float<> is what they call a backend, and you need to wrap it in a number<> adaptor in order to use it as an arithmetic type.

Here's my take on it: 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>(); } 

Output:

1405006117752879898543142606244511569936384000000000  1.40501e+51 

If convert_to<> is allowed, then the explicit conversion constructor will also work, I expect:

Dec decfloat(n); 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!