问题
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);
来源:https://stackoverflow.com/questions/23027285/how-to-convert-from-boostmultiprecisioncpp-int-to-cpp-dec-float0-rather-t