std::exp(-100.0f) == NaN?

Tob*_*ann 1 c++ floating-point gcc g++ nan

克++版本(5.4.0)返回NaN用于std::exp与浮体比约87小。

然而,文档std::exp 建议,它0适用于小数字:

如果参数是 -?,则返回 +0

这是标准库实现中的错误,还是我遗漏了什么?

效果可以这样重现:

#include <cmath>
#include <fenv.h>
#include <iostream>

int main()
{
    feenableexcept(FE_ALL_EXCEPT & ~FE_INEXACT);
    for (float x = 30; x > -1000; --x)
    {
        float y = std::exp(x);
        std::cout << x << "\t\t" << y << std::endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

30              1.06865e+13
29              3.93133e+12
28              1.44626e+12
27              5.32048e+11
...
-84             3.3057e-37
-85             1.2161e-37
-86             4.47378e-38
-87             1.64581e-38
Floating point exception
Run Code Online (Sandbox Code Playgroud)

S.M*_*.M. 5

您指定FE_UNDERFLOW 较早的浮点运算的结果低于正常且精度损失( 的位标志之一FE_ALL_EXCEPT)。可以表示的不等于零的最小值float是1e-38。之后x到达-88,你得到的浮点异常,而结果是6.0546e-39小于1e-38。不是NaN,您使用指令调整了异常的引发feenableexcept(FE_ALL_EXCEPT & ~FE_INEXACT)。

如果您删除位标志,FE_UNDERFLOW您的循环将输出零(或取决于平台的小的非零值)。