strtod ("nan") returns negative NaN

Masamichi Hosoda trueroad@trueroad.jp
Tue Aug 14 16:05:00 GMT 2018


[...]
>> > With your patch, strtold looks more correct, but it still prints the
>> > sign of NaN:
>> > 
>> >   strtod ("nan", NULL) = nan
>> >   strtod ("-nan", NULL) = nan
>> >   strtold ("nan", NULL) = nan
>> >   strtold ("-nan", NULL) = -nan
>> >   nan ("") = nan
>> > 
>> > Question: What's wrong with that?  Wouldn't it be more correct if
>> > strtod returns -NaN for "-nan" as well?
>> 
>> In my investigate,
>> strtold sets sign bit when parameter has '-' character.
>> The wrong long double NaN definition is negative NaN that is set sign bit.
>> So without my patch, both strtold ("nan") and
>> strtold ("-nan") return negative NaN.
>> 
>> On the other hand, strtod inverts the sign when parameter has '-' character.
>> The wrong double NaN definition is negative NaN.
>> So without my patch, strtod ("nan") returns negative NaN
>> and strtod ("-nan") returns positive NaN.
> 
> Your patch improves the situation, that's a sure thing and I did not
> question that.
> 
> I just wonder why returning -NaN when the input is "-nan" isn't the
> better approach.  After all:
> 
>   printf ("nan (\"\") = %f\n", nan (""));
>   printf ("-nan (\"\") = %f\n", -nan (""));
> 
> ==>
> 
>   nan ("") = nan
>   -nan ("") = -nan
> 
> So, shouldn't the ideal outcome be this:
> 
>   strtod ("nan", NULL) = nan
>   strtod ("-nan", NULL) = -nan
>   strtold ("nan", NULL) = nan
>   strtold ("-nan", NULL) = -nan
> 
> ?

On Linux,
strtof ("nan"), strtof ("-nan"),
strtod ("nan"), strtod ("-nan"),
strtold ("nan"), and strtold ("-nan")
all return positive NaN.

My patch is for closing to the behavior of Linux.
I don't know why Linux's strtod ("-nan") does not return negative NaN.
But, probably because both positive and negative NaN behave in the same way,
I think.

Here's sample code.
```
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

int main (void)
{
  double pnan = nan ("");
  double nnan = -pnan;

  printf ("positive NaN == positive NaN: ");
  if (pnan == pnan)
    printf ("true\n");
  else
    printf ("false\n");

  printf ("negative NaN == negative NaN: ");
  if (nnan == nnan)
    printf ("true\n");
  else
    printf ("false\n");

  printf ("0 < positive NaN: ");
  if (0 < pnan)
    printf ("true\n");
  else
    printf ("false\n");

  printf ("0 > positive NaN: ");
  if (0 > pnan)
    printf ("true\n");
  else
    printf ("false\n");

  printf ("0 < negative NaN: ");
  if (0 < nnan)
    printf ("true\n");
  else
    printf ("false\n");

  printf ("0 > negative NaN: ");
  if (0 > nnan)
    printf ("true\n");
  else
    printf ("false\n");
}
```

Result:
```
positive NaN == positive NaN: false
negative NaN == negative NaN: false
0 < positive NaN: false
0 > positive NaN: false
0 < negative NaN: false
0 > negative NaN: false
```

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple



More information about the Cygwin mailing list