Why is `isnan` returning 0 for a long double set to NAN?

222 views Asked by At
#include <stdio.h>
#include <math.h>

int main()
{
    long double x = NAN;
    printf("x = %Lg\nisnan(x) = %d\n", x, isnan(x));
    return 0;
}

When I run the above program, I get the output:

x = nan
isnan(x) = 0

According to the manpage, isnan is supposed to return a nonzero value when the argument is NaN. So why is it returning zero?

2

There are 2 answers

2
pmg On

Not sure this is relevant, but...

$ gcc so64374723.c -lm && ./a.out
x = nan
isnan(x) = 1

$ gcc -ffast-math so64374723.c -lm && ./a.out
x = nan
isnan(x) = 0

$ gcc -fsignaling-nans so64374723.c -lm && ./a.out
x = nan
isnan(x) = -1

$ clang -ffast-math so64374723.c -lm && ./a.out
x = nan
isnan(x) = -1

$ clang so64374723.c -lm && ./a.out
x = nan
isnan(x) = -1

3
Sparkette On

According to the same manpage, you are supposed to "link with -lm" when using isnan. After adding -lm to the gcc command line and recompiling, isnan(x) returned 1 like it's supposed to.

Not sure why it didn't give a linker error before though. I'd figure it would either not be implemented outside of libm, or it would be implemented correctly. Though I'm probably missing something.

EDIT: Setting -fsignaling-nans also works (thanks for the link @P__J__.) Interestingly it returns -1 in that case instead of 1, but this is still correct behavior as it's a nonzero value.