【问题标题】:Do-s and Don't-s for floating point arithmetic?Do-s 和 Don't-s 用于浮点运算?
【发布时间】:2010-06-23 14:35:21
【问题描述】:

对于浮点运算(IEEE754,以防出现混淆)有哪些好的注意事项和不注意事项,以确保您的结果具有良好的数值稳定性和高精度?

我知道有些人喜欢不要减去类似数量的数量,但我很好奇还有什么其他好的规则。

【问题讨论】:

  • 已经有很多关于 SO 处理这个问题的问题了。您是否进行了搜索,但没有找到任何答案?
  • 使用比较宏(C99 标准:7.12.14 比较宏)而不是 ==、>= 等运算符。
  • 这个问题的“答案”的累积性质似乎使它成为社区 Wiki 的主要候选者。

标签: c floating-point ieee-754


【解决方案1】:

首先,输入浮点数确实必须遵循与实数相同的规则的概念......一旦你接受了这一点,你就会明白大部分的陷阱。

以下是我一直遵循的一些规则/提示:

  • 永远不要将浮点数与零或其他任何东西进行比较(IE 不要这样做:if (myFloat == 0)
  • 关联属性不适用于浮点...意思是(a + b) + c != a + (b + c)
  • 记住,总是有四舍五入
  • 浮点数不一定有唯一的逆数
  • 浮点数没有闭包...永远不要假设浮点运算的结果是有效的浮点数。
  • 分配属性不成立
  • 尽量避免使用浮点比较...因为舍入错误会导致意外结果

【讨论】:

  • “永远不要假设浮点运算的结果是一个有效的浮点数。”除非您指的是 NAN 或无穷大,否则它将始终是另一个浮点数?
  • 对,对不起,我应该澄清一下......浮点运算可能不会产生实数:)
【解决方案2】:

浮点数的第一条“不要”规则是:

不要在整数就足够的情况下使用浮点数。

【讨论】:

    【解决方案3】:

    了解浮点的行为方式。

    不要相信简单的规则就足以正确使用它们。

    例如,至少有两个答案建议禁止比较浮点是否相等。首先,在某些情况下,需要比较它们是否相等。然后,当需要进行范围检查时,您还需要注意它有其缺陷,例如它不是传递性的,这是大多数人在相等性测试中会假设的属性。

    【讨论】:

    • +1。周围有太多教条的“从不比较浮点数是否相等”的答案。
    【解决方案4】:

    请记住,由于浮点运算错误people died 和数十亿美元的damages 发生了。

    【讨论】:

      【解决方案5】:

      永远不要尝试进行等式比较

      双 da,db;

      ...

      如果 (da==db) 那么什么。

      请记住,C 默认使用双精度,所以如果您想使用单精度,请清楚这一点

      浮动 fa,fb;

      ...

      fa = fb + 1.0;

      将 fb 转换为 double 执行双加然后转换为 single 并执行单个等于

      相反

      fa = fb + 1.0F。

      都是单身。

      如果您要使用像 1.0 这样的整数,请不要在代码中将其设为小数。如果您可以最小化 ascii 数字,您可以从编译器/工具中获得更高的可靠性。所以

      fa = fb + 1;

      或代替

      fa = fb + 0.3333333F;

      做这样的事情(如果对准确性感兴趣的话)。

      fc = 1; fc = fc / 3; fa = fb + fc;

      很多很多其他的,浮点是痛苦的,编译器和库不是那么好,fpus 有错误,而 IEEE 异常痛苦并导致更多错误。不幸的是,这就是我们在大多数平台上生活的世界。

      【讨论】:

        【解决方案6】:

        我避免浮点陷阱的“主要武器”是牢牢掌握它们的工作方式。我认为Chris Hecker 很好地解释了基础知识。

        【讨论】:

          【解决方案7】:

          搜索、下载和阅读 “每个计算机科学家都应该了解浮点运算”

          【讨论】:

          • 是的,但我不确定某处是否有“官方”。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-04-03
          • 1970-01-01
          • 2014-02-14
          • 1970-01-01
          • 2020-03-19
          • 2014-11-02
          相关资源
          最近更新 更多