具有固定精度的重载 boost::multiprecision::pow

Posted

技术标签:

【中文标题】具有固定精度的重载 boost::multiprecision::pow【英文标题】:Overload boost::multiprecision::pow with fixed precision 【发布时间】:2020-09-15 07:10:38 【问题描述】:

以下代码

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

typedef boost::multiprecision::number<boost::multiprecision::cpp_dec_float<50>, boost::multiprecision::et_off> float_50; 

int main()

    float_50 a = boost::multiprecision::pow((float_50)5, (float_50)10); // works
    double b = boost::multiprecision::pow((double)5, (double)10);       // doesn't work

    //double b = boost::multiprecision::pow<double>((double)5, (double)10); // Why can't be overloaded?
    return 0;

由于boost::multiprecision::pow 无法识别固定精度类型,因此无法编译。通常的解决方案是什么?我宁愿有一个pow 函数,它同时接受多精度和固定精度类型。我很奇怪 boost 常量,例如,有模板定义

boost::math::constants::pi<double>()
boost::math::constants::pi<float_50>()

工作正常。 boost::multiprecision::pow不应该也被重载吗?

【问题讨论】:

【参考方案1】:

solution 是离开命名空间。

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

typedef boost::multiprecision::number<boost::multiprecision::cpp_dec_float<50>, boost::multiprecision::et_off> float_50; 

int main()

    float_50 a = pow((float_50)5, (float_50)10); 
    double b = pow(5., 10.);      
    return 0;

【讨论】:

这里的 ADL 是有意的:如果可能,您想使用 pow 的 libc 版本(为了速度),并且在使用多精度类型时只使用更高精度的 multiprecision::pow。 我被抓住了,因为通常我们有一种偏执狂,即我们要具体说明我们调用的函数和命名空间等等。 这是一种合理的偏执狂,只是出于充分的理由才被推翻。 如果您查看常量,它们是长文本字符串,然后会被解析并四舍五入到精度。【参考方案2】:

单个函数无法处理不同类型的参数。对于每个受支持的参数集,您需要一个单独的函数。该函数可能是从模板自动生成的,但pow 似乎不是模板实现的候选对象。

【讨论】:

以上是关于具有固定精度的重载 boost::multiprecision::pow的主要内容,如果未能解决你的问题,请参考以下文章

如何在 .NET 中将双精度值转换为具有固定小数位数的小数类型值

如何在具有固定浮点的matlab中转换变量

高精度重载运算符

类和对象(17)—— 操作符重载

decimal模块

c++函数重载,具体步骤是啥