简体   繁体   中英

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

g++ version ( 5.4.0 ) returns NaN for std::exp with floats smaller than roughly 87.

However the docs to std::exp suggest, that it approaches 0 for small numbers:

If the argument is -∞, +0 is returned

Is this a bug in the implementation of the standard library, or what am I missing?

The effect can be reproduced like this:

#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;
    }
}

Output:

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

You specify FE_UNDERFLOW the result of the earlier floating-point operation was subnormal with a loss of precision (one of bit flags of FE_ALL_EXCEPT ). The minimum value not equal to zero that can be represent by float is 1e-38 . After x reaches -88 , you get the floating point exception while the result is 6.0546e-39 that is less than 1e-38 . It is not NaN , you tuned raise of the exception with the instruction feenableexcept(FE_ALL_EXCEPT & ~FE_INEXACT) .

If you remove the bit flag FE_UNDERFLOW your loop will output zeros (or small not zero values depending on a platform).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM