【问题标题】:In C, error handling with an IF statement在 C 中,使用 IF 语句进行错误处理
【发布时间】:2021-10-26 23:45:40
【问题描述】:

我需要修复一些代码

if ( abs(( (a/b) - (c/d) ) / (a/b)) > 0.1) { ... 

这是检查这些值是否有意义的一部分。如果不是,它将重新查询这些值。事先进行检查以确保它在任何点都不会被零除,但该等式有时会出现浮点下溢错误。我正在尝试找出一种方法来运行它以消除任何可能的错误。

Try and catch 已经退出,因为这是在 C 而不是 C++ 中,setjmp 和 longjmp 似乎只有在你可以自己“抛出”错误时才有效(我没有看到任何例子是程序导致触发它的错误)

我的解决方案可以编译但很难测试(因为它是整个系统的一部分):

if (val = abs(( (a/b) - (c/d) ) / (a/b)){
      if (val > 0.1) {

如果'if'语句中的语句试图抛出错误,它会停止程序还是跳过if语句?

欢迎提出其他意见

【问题讨论】:

  • 我认为没有任何方法可以检测 C 中的浮点下溢/溢出。
  • “if”语句如何引发错误?什么错误?
  • 这不是您问题的答案,但将这个条件包装在一个具有有意义名称的函数中肯定会很有用。
  • 如果系统不依赖于该特定计算来继续,则为每个计算添加逻辑并在计算之前记录任何会破坏计算的传入值可能会更安全。例如。检查 (a/b) - (c/d) 和 (a/b) 的范围并检测上溢或下溢。这是什么硬件导致下溢?
  • 你为什么要计算 (a/b - c/d) / (a/b) 而不是代数等价的 1 - (b*c)/(a*d)?您是否正在尝试处理一些数字问题?

标签: c error-handling


【解决方案1】:

常见的 C 实现在浮点除以零时继续,结果设置为 +∞、-∞ 或 NaN,具体取决于操作数。在执行除法之前,您应该测试 ba/b 以查看它们是否为零,并且您还应该考虑其他感兴趣的条件,例如 NaN。例如,如果 a/bc/d 溢出,您的计算将导致 NaN 与 .1 进行比较,这将评估为 false,因此代码将无法检测到这一点,但您可能希望将其视为一个错误。

另外,abs 是一个 int 函数。对于浮点绝对值,使用fabsffabsfabsl,对于floatdoublelong double

【讨论】:

    【解决方案2】:

    如果'if'语句中的语句试图抛出错误,它会停止程序还是跳过if语句?

    假设首先定义了外部if 条件中表达式的行为,唯一的选择是它计算为浮点值(可能是无穷大或NaN),或者它执行一个陷阱.

    后者是我对“抛出错误”的意思的最佳猜测,如果程序执行了一个陷阱,那么根据定义,它会在那时和那里中断它的执行(但不一定没有继续的可能性) .这与执行陷阱的上下文完全无关。

    浮点下溢导致陷阱不是大多数系统的默认行为,但许多系统提供了针对诸如此类的异常 FP 条件启用陷阱的可能性。一种选择是简单地将其关闭,至少在评估该条件时。它可能看起来像这样:

    #include <fenv.h>
    #pragma STDC FENV_ACCESS ON
    
    // ...
    
        fenv_t env;
    
        // Preserve the current FP environment and set a mode that prevents trapping
        // when FP exceptions are raised.
        feholdexcept(&env);
    
        if ( abs(( (a/b) - (c/d) ) / (a/b)) > 0.1) {
            // ... 
        }
    
        // Restore the FP environment
        fesetenv(&env);
    

    【讨论】:

      【解决方案3】:

      C 不允许异常......你的程序将停止。

      【讨论】:

      • C 标准没有定义除以零的行为。常见的 C 实现将整数除以零,但浮点除以零,根据操作数,商为 +∞、-∞ 或 NaN,并且问题提到了浮点。
      猜你喜欢
      • 1970-01-01
      • 2017-02-17
      • 1970-01-01
      • 1970-01-01
      • 2012-09-17
      • 1970-01-01
      • 1970-01-01
      • 2017-03-03
      • 2013-08-16
      相关资源
      最近更新 更多