我正在尝试将浮点数舍入到两个小数点,但这是不正确的。如何修复C ++中的舍入错误?

时间:2019-07-13 20:08:01

标签: c++ floating-point rounding floating-accuracy rounding-error

我在舍入浮点数时遇到麻烦。我正在解决一项任务,您需要将结果四舍五入到小数点后两位。但是当第三个小数点是5时,我不能这样做,因为它存储不正确。

例如:我的结果等于1.005,应该四舍五入为1.01。但是C ++将其四舍五入为1.00,因为原始浮点存储为1.0049999 ...而不是1.005。

我已经尝试过总是在结果中添加一个很小的浮点数,但是还有其他一些测试用例会被四舍五入,但是应该四舍五入。

我知道浮点是如何工作的,并且它常常不完全准确。我只是想知道是否有人找到解决此特定问题的方法。

2 个答案:

答案 0 :(得分:1)

当您说“我的结果等于1.005”时,即表示您在计算真实的十进制数字。可以是1.005(小数部分的三位数),1.0050(四位数字),1.005000,依此类推。

因此,您应该首先使用一些常用的舍入方法将其舍入到该位数。用整数更容易做到这一点:例如,使用6个小数位,这意味着在乘以1,000,000后通常会使用一些round()rint()等。通过此步骤,您将获得准确的十进制数字。之后,您就可以根据需要进行最终的四舍五入了。

在您的示例中,这将把1,004,999.99 ...舍入为1,005,000。然后,除以10000,然后再次取整。

(注意,建议以特定的方式进行此舍入。General Decimal Arithmetic规范和IBM算术手册建议,这种舍入的方式是将精确的小数部分0.5舍入为零,除非最小为零。有效结果位变为0或5,在这种情况下,它会四舍五入为零。但是,如果您没有这样的舍入方法,则一般也可以从零开始。)

如果要实现货币核算算法,则完全避免浮点并使用定点算法(必要时用整数模拟)是合理的。这样做会更好,因为您描述的四舍五入方法不可避免地包含到整数的转换(然后再返回),因此,直接使用此类整数会更便宜。您还将获得不精确的操作检查(通过显式整数溢出的代价)。

答案 1 :(得分:0)

如果可以使用具有Multiprecision支持的boost之类的库。
另一种选择是使用long double,也许对您来说足够精确。