Boost,在任意精度浮点数和整数类型之间转换

Boost, converting between arbitrary precision floating point and integral types

我完全不知道应该如何真正做到这一点,在我尝试 运行 ceil() 之前,我大部分时间都设法让我的代码工作 cpp_dec_float<0>打到什么时候会在我身上爆炸拒绝合作,仔细查看boost文档和google搜索后我得出结论,我无法自己找到答案,因此我在这里寻求无限的帮助更有能力的程序员。

#include <iostream>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/math/special_functions/pow.hpp>
#include <boost/chrono/ceil.hpp>
#include <boost/multiprecision/number.hpp>

namespace mp = boost::multiprecision;
using namespace std;
using namespace boost::math;
using namespace boost::chrono;
using Int = mp::cpp_int;
Int reward(Int baseReward, int percent);

int main(int argc, char** argv)
{

    reward = calcReward(immBase, percent);
    return 0;
}

Int calcReward(Int baseReward, int percent)
{
    using Dec  = mp::number<mp::cpp_dec_float<0>>;
    Dec mult   = 0.1+0.01*percent;
    Dec five   = 5;
    Dec base   = baseReward.convert_to<Dec>();
    Int result = ceil(five*base*mult);

    return result;
}

这是从不必要的垃圾中剥离出来的代码,五个变量是一个肮脏的黑客,让它接受与任意精度浮点值的乘法(因为它只是决定说没有匹配的运算符 * 否则) . 这相当令人困惑且非常令人沮丧, ceil().convert_to() 也不起作用并吐出一个任意的无法破译的错误。 (模板错误不可读)

此代码在编译时确实需要 -std=c++11 标志,这可能是显而易见的。

通常的罪魁祸首是 BMP 表达式的结果不是它们的目标类型,但仍然是 "lazy" 表达式模板,并且它们没有所有的隐式转换。因此,您需要评估这些 "manually"(明确地):

return Dec(ceil(five*base*mult)).convert_to<Int>();

看到了Live On Coliru

#include <iostream>
#include <boost/multiprecision/detail/default_ops.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/math/special_functions/pow.hpp>
#include <boost/multiprecision/number.hpp>

namespace mp = boost::multiprecision;

using Int = mp::cpp_int;

Int calcReward(Int baseReward, int percent);

int main()
{
    Int const immBase = 400;
    int const percent = 12;

    std::cout << calcReward(immBase, percent);
}

Int calcReward(Int baseReward, int percent)
{
    using Dec  = mp::cpp_dec_float_50;
    Dec mult   = 0.1+0.01*percent;
    Dec five   = 5;
    Dec base   = baseReward.convert_to<Dec>();

    return Dec(ceil(five*base*mult)).convert_to<Int>();
}

备注:

  • 或者,禁用表达式模板

    using Int = mp::number<mp::cpp_int::backend_type, mp::et_off>;
    using Dec  = mp::number<mp::cpp_dec_float<50>, mp::et_off>;
    
  • 计时包括不相关

  • ceil由于ADL(What is "Argument-Dependent Lookup" (aka ADL, or "Koenig Lookup")?)
  • 可以不合格使用