# feclearexcept

< c‎ | numeric‎ | fenv

定义于头文件 `<fenv.h>` |  |
int feclearexcept( int excepts ); |  | (C99 起)

尝试清除列于位掩码参数 `excepts` 的浮点异常，该参数值为浮点异常宏的逐位或。

### 参数

excepts | - | 列出带清除的异常标志的位掩码

### 返回值

若成功清除所有指明的异常，或若 `excepts` 为零则返回 ​0​ 。错误时返回非零。

### 示例

    #include <fenv.h>
    #include <stdio.h>
    #include <math.h>
    #include <float.h>

    /*
     * 可能的hypot实现，它会活用许多高级浮点特性。
     */
    double hypot_demo(double a, double b) {
      const int range_problem = FE_OVERFLOW | FE_UNDERFLOW;
      feclearexcept(range_problem);
      // 尝试快速算法
      double result = sqrt(a * a + b * b);
      if (!fetestexcept(range_problem))  // 未上溢或下溢
        return result;                   // 返回结果
      // 做更多复杂计算以避免上溢或下溢
      int a_exponent,b_exponent;
      frexp(a, &a_exponent);
      frexp(b, &b_exponent);

      if (a_exponent - b_exponent > DBL_MAX_EXP)
        return fabs(a) + fabs(b);        // 我们可以忽略小值
      // 令fabs(a)的规模接近1
      double a_scaled = scalbn(a, -a_exponent);
      double b_scaled = scalbn(b, -a_exponent);
      // 现在上溢和下溢是不可能的
      result = sqrt(a_scaled * a_scaled + b_scaled * b_scaled);
      // 撤销规模化
      return scalbn(result, a_exponent);
    }

    int main(void)
    {
      // 通常情况选择较快的路线
      printf("hypot(%f, %f) = %f\n", 3.0, 4.0, hypot_demo(3.0, 4.0));
      // 极限情形会选择较慢但更准确的路线
      printf("hypot(%e, %e) = %e\n", DBL_MAX / 2.0,
                                    DBL_MAX / 2.0,
                                    hypot_demo(DBL_MAX / 2.0, DBL_MAX / 2.0));

      return 0;
    }

输出：

    hypot(3.000000, 4.000000) = 5.000000
    hypot(8.988466e+307, 8.988466e+307) = 1.271161e+308

### 引用

- C11 标准（ISO/IEC 9899:2011）：

  - 7.6.2.1 The feclearexcept function (p: 209)

- C99 标准（ISO/IEC 9899:1999）：

  - 7.6.2.1 The feclearexcept function (p: 190)

### 参阅

fetestexcept (C99) | 确认设置了哪些浮点异常状态标志 (函数)