c++ - 如何将 cpp_dec_float_50 转换为 cpp_int?关于一般的 float ?

标签 c++ boost floating-point

我的基本目标是减去两个应该相等的 float 。 考虑一下:-

float x=1;
float a=x/30-x/40;    
float b=x/30;
b-=x/40;
std::cout<<a-b<<std::endl;

我应该得到零分。但我没有。相反,我得到了一个非常小的数字,大约 10^(-10)。

现在,有两个选择:-

首先,我想到用有理式代替分数(即处理分子和分母),然后将最终的有理式转化为分数。我通过 Boost.rational 做到了这一点。我使用 cpp_int 来存储分子和分母,因为分子和分母可能会变得很大。它工作正常。但问题是我正在制作的程序要花很多时间。我认为这是因为必须处理巨大的整数。

其次,有人建议我尝试定点运算。我不是很擅长。所以,我不确定定点算术是否也能给出正确答案?我在想的是这个-> 假设我希望我的减法结果正确到第 50 位精度。因此,我通过将小数点乘以 10 的适当幂得到小数点左侧的 50 位数字。删除小数部分并将其转换为 cpp_int。我对两个花车都这样做。然后对这些cpp_int进行减法。 两个问题:- 首先,我无法将 cpp_float_dec_50 转换为 cpp_int。 Boost 不允许直接进行这种(有损)转换。 其次,我对这种方法完全没有信心。

所以,最后两个问题:- 如何将 cpp_float_dec_50 转换为 cpp_int? 到目前为止,在问题中提出的上下文中,哪种方法是最好的二减二 float ?

谢谢。很抱歉,如果其中任何一个被视为非常菜鸟或愚蠢的问题。 我还在学习。

最佳答案

您需要决定是否需要精确表示。如果 10^-10 是一个太大的错误,毕竟你可能想要精确性。我可以说定点表示本身并不比内置类型好;如果你扩展它的精度和功能,你就会得到一个多精度库:)。

我可以推荐boost::multiprecision , 并且发现它相当简单,尽管因为它是一个 boost 模板库,所以需要一些额外的努力来查找编译器错误。数字转换很管用,当然天下没有“免费的午餐”;如果使用错误,您的结果就像内置数字一样容易搞砸。

注意事项:

  • 性能是精度的函数。控制住它!
  • 随着时间的推移衡量您的精确度。例如,重复乘法可能会无限制地增加精度。消除数学中不必要的转换。
  • 许多函数(例如 trig、log、exp 等)并未针对有理数实现。在您需要放弃并接受受控错误(通过使用浮点类型)之前,您只能非常小心地绕过此类数学。
  • 您可以根据其精度要求分离您的程序。例如,在 2D 渲染时,转换到 View 空间 (-1..1),然后您可以将值截断为 float 并以极快的速度运行。
  • boost::multiprecision 有许多后端可以 boost 性能(尽管它们不会修复精度控制方面的错误)

我对我的 boost mp 类型使用以下定义。就我而言,我发现关闭表达式模板会更快。

namespace mp = boost::multiprecision;
typedef mp::number<mp::cpp_int_backend<>, mp::et_off>       int_mp;
typedef mp::number<mp::cpp_rational_backend, mp::et_off>    rational_mp;
typedef mp::number<mp::cpp_dec_float<0>, mp::et_off>        float_mp;  // 0 means 'unlimited'

关于c++ - 如何将 cpp_dec_float_50 转换为 cpp_int?关于一般的 float ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16033578/

相关文章:

c++ - 二维数组计算公式

python-3.x - Python打印具有给定位数的 float

c - 浮点函数总是返回 0.000000

javascript - JavaScript中如何处理 float 精度?

c++ - 如何通过使用sql查询仅将值添加到一张表来将值插入到不同的表中?

c++ - 我应该为我的目的使用哪种数据结构?

c++ - VS2017 version 15.8.3 成功编译内联方法不返回所需值

c++ - 通过 boost 信号 2 的观察者模式

boost - 基于分布的弱学习器 : Decision stump

c++ - 为什么 boost circular_buffer 不存储我的 bool 值?