【问题标题】:What is the best way to deal with floating point errors?处理浮点错误的最佳方法是什么?
【发布时间】:2015-06-12 20:10:52
【问题描述】:

所以我有一个 Javascript 脚本,它在一个循环中将小部分加在一起,它可能会将 0.2 添加到 0.1。然后将该值提供给另一个函数,但问题是我需要准确地提供 0.3 而不是 0.30000000000000004。

确保数字正确无误的最简单方法是什么。请注意,将 0.25+0.125 等添加到简单的四舍五入到小数点后不会解决问题。

也可以添加 0.2 + 0.10000000000000004,尽管这非常非常不可能!

【问题讨论】:

  • 0.25+0.125 是一个不寻常且简单的案例。两个值及其总和都可以精确表示,因此不存在舍入误差。 0.3 的情况并非如此。您可以获得的最接近的是 0.299999999999999988897769753748434595763683319091796875。够近了吗?
  • 这不是一个解决方案,但你的数学越笨,越准确
  • 您的小号是如何制作的?您最好将所有内容乘以1000
  • 你可以使用 (parseFloat('0.1') + parseFloat('0.1')).toFixed(2);如果您想要小数点后的 n 位数,请将 n 添加到固定
  • 有一个类似的问题here,也可以查看你的BigNumber

标签: javascript floating-point numbers


【解决方案1】:

在通用浮点运算中没有避免舍入错误的简单方法。数字0.3 没有精确的二进制浮点表示。

我建议阅读What Every Computer Scientist Should Know About Floating-Point Arithmetic 以熟悉数字浮点表示固有的权衡。

要真正解决您的问题,您应该问自己几个问题:

  • 您对精度的要求有多严格?为什么0.30000000000000004 超出您的容错范围?是否可以对结果进行四舍五入?
  • 有什么方法可以表示数字并用整数执行大部分算术运算?例如。如果您知道您只会遇到有理数,则可以使用整数商和整数分母来表示它们。从那里,您可以尝试尽可能长时间地推迟转换为浮动,以防止累积舍入错误。
  • 如果您无法对整数执行计算,是否可以使用其他数据类型,例如 BigDecimal

最终,当涉及浮点精度问题时,您通常必须根据特定问题提出的要求定制解决方案。

【讨论】:

    猜你喜欢
    • 2017-11-13
    • 2017-12-26
    • 2020-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-06
    相关资源
    最近更新 更多