我正在用 C 编写一个浮点计算器接口(interface),它允许在运行时访问 math.h 中定义的数学函数。该接口(interface)作为函数实现,其行为类似于 strtold()。它基于 ASCII,应该像 ASCII 一样可移植,但为了实现这一点,我需要以尽可能可移植的方式处理 float 。我很高兴限制对 IEEE-754 float 的支持,但我不确定如何处理 IEEE-754 定义的异常(溢出、下溢等)。首先,我非常确定在所有舍入模式下检查异常的唯一方法是检查状态标志本身;为此,我需要 fenv.h(在 C99 的附件 F 中定义),所以我想知道 fenv.h 在实践中的可移植性。我也不完全理解 fenv.h 应该如何工作;在我看来,状态标志是集中的,但无论出于何种原因,我的印象是每个 float 都内置了标志。我也知道 C99 说 math.h 中定义的函数可能会溢出和下溢,但我不明白我应该如何检查这些异常。因此,总而言之,我正在寻找一个示例,说明如何使用 fenv.h 检查由乘法引起的溢出,以及如何正确检查 math.h 中定义的函数的错误。
最佳答案
理论上,以下函数将两个数相乘,如果发生溢出则返回 true
,否则返回 false
:
bool mul(double &a, double b) {
feclearexcept(FE_OVERFLOW);
a *= b;
return fetestexcept(FE_OVERFLOW) != 0;
}
标准规定您需要 #pragma FENV_ACCESS ON
才能使用它。但是,我还没有使用关心那个编译指示的编译器,或者知道浮点乘法有一个副作用反射(reflect)在异常标志中的编译器——gcc 和 clang 都会愉快地“优化掉”一个“死”浮点运算。 gcc bug 34678关注这种行为,我想有一个类似的针对 clang 的错误。此警告也适用于在程序中使用舍入模式以外的任何舍入模式。
关于c - C 中的 IEEE-754 浮点异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30181932/