【问题标题】:Which is the best approach to handle floating point exceptions in embedded code?在嵌入式代码中处理浮点异常的最佳方法是什么?
【发布时间】:2012-10-18 20:59:43
【问题描述】:

我正在开发一个安全关键的嵌入式程序(C 语言),我想在其中使用 IEEE 754 浮点算法(使用 NaN 和 Infs)进行工程计算。在这里,我有两种方法(afaik)来处理浮动 点例外:

  • 如果发生任何异常,则进入永久故障状态。从错误检测的角度来看,这可能更健壮,但对容错/可用性不利。
  • 忽略异常,并检查最终结果是有限数(计算成功)还是 NaN,inf(计算失败)。这种解决方案容错性更强,但风险更大,因为输出 可能会意外地被排除在检查之外。

    1. 在安全关键系统中,哪种解决方案更好?
    2. 还有其他选择吗?
    3. 如果计算的复杂性不允许第一个解决方案(我无法避免正常使用中的异常),最后的检查是否足够,还是我应该考虑其他方面?

【问题讨论】:

  • 什么嵌入式微处理器?它们特定于所讨论的微控制器/微处理器。还可以查看如何在长序列中进行惰性评估,以及微控制器/微处理器浮点单元中的 NaN 和 Inf 是什么意思
  • SH2,它的 FPU 符合 IEEE754,所以我有两种选择。
  • 可能不把所有异常都一视同仁。有些可能像非规范化下溢一样无害,而 NaN 或除以零可能完全出乎意料

标签: c floating-point-exceptions


【解决方案1】:
  1. 在安全关键系统中哪个更好取决于系统,如果没有更多信息就无法回答。

  2. 另一种选择是设计浮点代码,使其不会出现不希望的行为(或可以根据需要进行处理)并为此编写证明。

  3. 通常,检查最终值不足以检测计算过程中是否发生异常或其他错误。

关于3,考虑到各种异常结果可能在后续操作中消失。当用作除数时,无穷大可以产生零。 NaN 在最小值或最大值的某些实现中消失。 (例如,max(3, NaN) 可能产生 3 而不是 NaN。)分析您的代码可能(或可能不会)揭示这些事情在您的特定计算中是否可能。

但是,检查最终值的另一种方法是检查异常标志。 IEEE 754 的大多数实现都有累积标志——一旦发生异常,它的标志就会被提升并保持提升直到显式重置。因此,您可以在计算开始时清除标志并在结束时对其进行测试,并且与测试最终值不同,这将保证您在异常发生后观察到它们。

【讨论】:

  • 2:您是指限制输入还是如何限制输入?这将不可能计算出这些复杂计算肯定不会失败的输入范围。
  • 代码中可能会发生除以 inf 的情况,但大多数情况下结果是一个很好的近似值。否则我没有考虑对 NaN 的关系操作。这可能会导致一些问题。您检查异常标志的建议似乎比检查结果更合适。谢谢。
  • @simon: 2 是开放式的。它在很大程度上取决于应用程序,取决于所涉及的特定计算。例如,在某些情况下,计算的理想函数表现良好并且不会产生错误,但可能会出现错误,因为浮点舍入会扰乱数据。 (例如,如果 x 在理想计算中始终不大于 sqrt(3),则 sqrt(3-x^2) 始终为实数。但如果浮点舍入使 x 略大于 sqrt(3),则 sqrt( 3-x^2) 得到一个错误。)有时你可以设计代码来避免这些问题,也许通过证明 x 永远不会太大或通过明确限制 x。
  • @simon:零似乎是非常小的结果的一个很好的近似值,但考虑评估x/(2*y),之前的操作导致xy 分别为0x1p1023。然后2*y 计算为无穷大,x/(2*y) 计算为 0,但数学上的精确值为 1/2。这不是一个很好的近似值。
  • 很好的例子,谢谢。我写了“大部分时间”,因为这可能比我的代码中对 nan 的关系操作发生的次数少得多。
猜你喜欢
  • 2015-06-12
  • 2011-04-29
  • 1970-01-01
  • 2021-02-22
  • 1970-01-01
  • 1970-01-01
  • 2010-12-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多