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

I'm trying to round a float to two decimal points but it's incorrect. How to fix this rounding error in C++?

提问人:Hinko Pih Pih 提问时间:7/14/2019 最后编辑:Hinko Pih Pih 更新时间:7/14/2019 访问量:600

问:

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

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

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

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

C++ 浮点 精度 舍入误差

评论

1赞 john 7/14/2019
您所做的任何事情都无法改变 1.0049999.应四舍五入为 1.00 的事实。你只需要接受浮点运算并不完全准确。
3赞 7/14/2019
浮点数学是否损坏的可能重复?
1赞 Jesper Juhl 7/14/2019
一些推荐阅读: 有时浮点数学是完美的每个计算机科学家都应该知道的关于浮点运算的知识
0赞 Eric Postpischil 7/14/2019
你如何计算你想要四舍五入的数字?由于您拥有的代码生成的数字不完全是 1.005,但您希望它恰好生成 1.005,因此解决方案是将该代码更改为使用另一种可以精确表示 1.005 的格式,而不是尝试创建一个例程,在输入不正确的情况下返回正确舍入的结果。
1赞 Nelfeal 7/14/2019
@HinkoPihPih 嗯,你在另一条评论中说你只允许“常规C++图书馆”;如果你指的是标准库,那么你就不走运了。否则,只需搜索十进制库即可。我敢肯定,您甚至可以找到一些仅标题的标题。

答:

0赞 Rick Pat 7/14/2019 #1

如果您可以使用像 boost 这样的库及其多精度支持。
另一种选择是使用 ,也许这对你来说已经足够精确了。
long double

评论

0赞 Hinko Pih Pih 7/14/2019
这对我没有帮助,因为我们的学校系统只允许常规的 C++ 库。
1赞 Netch 7/14/2019 #2

当你说“我的结果等于 1.005”时,你假设有一些真正的十进制数字。这可以是 1.005(小数部分的三位数字)、1.0050(四位数字)、1.005000 等。

因此,您应该首先使用一些通常的四舍五入到该位数。在整数中执行此操作更简单:例如,对于 6 个小数,表示乘以 1,000,000 后的一些常用 、 等。通过此步骤,您将获得确切的十进制数。在此之后,您可以根据需要进行所需的最终四舍五入。round()rint()

在您的示例中,这将舍入 1,004,999.99...到1,005,000。然后,除以 10000 并再次四舍五入。

(请注意,有一些建议以特定的方式进行此舍入。通用十进制算术规范和 IBM 算术手册建议,这种舍入方式是精确小数部分 0.5 应从零四舍五入,除非最低有效结果位变为 0 或 5,在这种情况下,它向零四舍五入。但是,如果您没有这样的舍入可用,则一般的远离零也是合适的。

如果要为货币会计实现算术,则完全避免浮点并使用定点运算(如果需要,使用整数模拟)是合理的。这更好,因为我描述的舍入方法不可避免地包含到整数(和返回)的转换,因此,直接使用此类整数更便宜。您还将获得不精确的操作检查(按显式整数溢出的成本计算)。