如何从cpp_dec_foat_50转换为cpp_int?关于一般的浮动点

How to convert from cpp_dec_float_50 to cpp_int? And regarding floating points in general?

本文关键字:cpp 于一般 int 转换 dec foat      更新时间:2023-10-16

我的基本目标是减去两个应该等效的浮点值。考虑一下:-

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.rerational实现的。我使用cpp_int来存储分子和分母,因为分子和分母可能会变得巨大。它运行良好。但问题是我正在制作的这个节目花了很多时间。我认为这是因为必须处理巨大的整数。

其次,有人建议我尝试不动点运算。我不太擅长。所以,我不确定定点算术是否也能给出正确的答案?我当时想的是->假设我想把减法的结果校正到第50个精度。因此,我将小数点左边的50位数字乘以10的适当幂。删除小数部分并将其转换为cpp_int。我用两个浮子都这样做。然后对这些cpp_int执行减法运算。两个问题:-首先,我无法将cpp_float_dec_50转换为cpp_int。Boost不允许直接进行这种(有损(转换。其次,我只是对这种方法的有效性没有信心。

所以,最后有两个问题:-如何将cpp_float_dec_50转换为cpp_int?到目前为止,在问题中提出的上下文中,什么样的方法是最好的两减两浮点数?

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

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

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

需要牢记的事项:

  • 性能是精度的函数。控制住它
  • 随着时间的推移测量你的精度。例如,重复乘法可能会增加精度而不受约束。消除数学中不必要的转换
  • 许多函数(例如trig、log、exp…(不是为推理而实现的。在你需要放弃并接受可控误差(通过使用浮点类型(之前,你只能非常小心地绕过这样的数学
  • 您可以根据程序的精度要求将其分离。例如,当在2D中渲染时,转换到视图空间(-1..1(,然后可以将值截断为浮点,并以良好的速度进行操作
  • boost::multiprecision有许多可以提高性能的后端(尽管它们不会修复精度控制方面的错误(

我对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'