问题描述
我们正在编写对具有 8 个固定十进制数字(.
后的 8 个十进制数字)的数字进行算术运算的软件。
我们曾几次被内置浮点类型(例如 double
)的有限精度所困扰,主要是在相等比较上(在小数点 17 左右失败)。所以我们尝试转向一些固定精度十进制类型。
从它的文档来看,cpp_dec_float
应该是这样的类型。
所以我们用 using Decimal = double
using Decimal = boost::multiprecision::number<boost::multiprecision::cpp_dec_float<8>>;
如果我们从字符串实例化 Decimal
一切正常,但是当它从浮点文字实例化时会变得复杂:
assert(Decimal{0.001} == Decimal{"0.001"});
上述断言失败,因为左侧的 Decimal 实例似乎带有用于初始化它的文字的不精确表示,即使这个 epsilon 远远超出了所要求的精度 8。
有没有办法获得“在实例化时截断”的行为,从而满足上述断言? (理想情况下,该解决方案不需要接触发生此类实例化的所有调用站点)
解决方法
这可以解释:
0.001 as a 32 bit float is exactly:
0.0009999999310821295
12345678 are the 8 digits of accuracy
0.0009999999 is 0.001 as a 32 bit float rounded to the 8 digits of accuracy
0.0010000000 is 0.001 truely ecarately
VS 7 bits of accuracy:
0.0009999999310821295
1234567
0.001000000
0.001000000