0
#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?

flarn2006
  • 1,787
  • 15
  • 37
  • 1
    compile with the option "-fsignaling-nans" – 0___________ Oct 15 '20 at 15:40
  • @P__J__ Yep, I figured that out from the link you posted in another comment and edited it into my answer. If you post that as an answer, I'll accept it (unless someone else posts an even better one.) – flarn2006 Oct 15 '20 at 15:49

2 Answers2

1

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

pmg
  • 106,608
  • 13
  • 126
  • 198
  • you are very close. https://gcc.gnu.org/wiki/FloatingPointMath . gcc has to be compliled with option allowing signaling NaNs ( which most modern provided gcc binaries do) – 0___________ Oct 15 '20 at 15:39
  • Hmmm ... I'm using an older version of gcc: `6.3.0 20170516` – pmg Oct 15 '20 at 15:42
-1

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.

flarn2006
  • 1,787
  • 15
  • 37
  • Because it is macro not function. Nothing to ro with linker – 0___________ Oct 15 '20 at 15:30
  • @P__J__ I'm aware of that, but then why would it not work if I don't link with `-lm`? I figure the macro probably uses something that relies on `-lm` in some way, but I don't know what that could be that wouldn't give an error if it's missing. – flarn2006 Oct 15 '20 at 15:41
  • it cant relay on anything in libm. Otherwise, we would get linker error – 0___________ Oct 15 '20 at 15:44