public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
* `std::stod ("nan")` returns negative NaN
@ 2018-08-13 15:16 Masamichi Hosoda
  2018-08-13 16:53 ` Stephen John Smoogen
  0 siblings, 1 reply; 32+ messages in thread
From: Masamichi Hosoda @ 2018-08-13 15:16 UTC (permalink / raw)
  To: cygwin; +Cc: trueroad

Hi

I've found a curious behavior about `std::stod ("nan")` on Cygwin.
Only on Cygwin, `std::stod ("nan")` returns negative NaN.
On Linux etc., `std::stod ("nan")` returns positive NaN.

Here is a reproduction code.

```
// g++ -std=c++11 foobar.cc

#include <iostream>
#include <limits>
#include <string>

int main ()
{
  std::cout << "stod (\"nan\") = "
            << std::stod ("nan")
            << std::endl;
  std::cout << "stod (\"-nan\") = "
            << std::stod ("-nan")
            << std::endl;

  std::cout << "quiet_NaN () = "
            << std::numeric_limits<double>::quiet_NaN ()
            << std::endl;
}
```

The result on Cygwin 2.10.0 64 bit (g++ 7.3.0):
```
stod ("nan") = -nan
stod ("-nan") = nan
quiet_NaN () = nan
```

The result on MinGW-w64 64 bit (g++ 4.9.2):
```
stod ("nan") = nan
stod ("-nan") = nan
quiet_NaN () = nan
```

The result on Ubuntu 16.04 LTS 64 bit (g++ 5.4.0):
```
stod ("nan") = nan
stod ("-nan") = nan
quiet_NaN () = nan
```

The result on FreeBSD 10.1 64 bit (clang++ 3.4.1):
```
stod ("nan") = nan
stod ("-nan") = nan
quiet_NaN () = nan
```

Is it correct that returning negative NaN on Cygwin?

Thanks.

--
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

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: `std::stod ("nan")` returns negative NaN
  2018-08-13 15:16 `std::stod ("nan")` returns negative NaN Masamichi Hosoda
@ 2018-08-13 16:53 ` Stephen John Smoogen
  2018-08-13 23:46   ` Duncan Roe
  0 siblings, 1 reply; 32+ messages in thread
From: Stephen John Smoogen @ 2018-08-13 16:53 UTC (permalink / raw)
  To: cygwin; +Cc: trueroad

On Mon, 13 Aug 2018 at 11:16, Masamichi Hosoda <trueroad@trueroad.jp> wrote:
>
> Hi
>
> I've found a curious behavior about `std::stod ("nan")` on Cygwin.
> Only on Cygwin, `std::stod ("nan")` returns negative NaN.
> On Linux etc., `std::stod ("nan")` returns positive NaN.
>
> Here is a reproduction code.
>
> ```
> // g++ -std=c++11 foobar.cc
>
> #include <iostream>
> #include <limits>
> #include <string>
>
> int main ()
> {
>   std::cout << "stod (\"nan\") = "
>             << std::stod ("nan")
>             << std::endl;
>   std::cout << "stod (\"-nan\") = "
>             << std::stod ("-nan")
>             << std::endl;
>
>   std::cout << "quiet_NaN () = "
>             << std::numeric_limits<double>::quiet_NaN ()
>             << std::endl;
> }
> ```
>
> The result on Cygwin 2.10.0 64 bit (g++ 7.3.0):
> ```
> stod ("nan") = -nan
> stod ("-nan") = nan
> quiet_NaN () = nan
> ```
>

On Fedora 27 with 7.3.1 it gives
```
stod ("nan") = nan
stod ("-nan") = nan
quiet_NaN () = nan
```
So it looks like it is a library problem of some sort.

> The result on MinGW-w64 64 bit (g++ 4.9.2):
> ```
> stod ("nan") = nan
> stod ("-nan") = nan
> quiet_NaN () = nan
> ```
>
> The result on Ubuntu 16.04 LTS 64 bit (g++ 5.4.0):
> ```
> stod ("nan") = nan
> stod ("-nan") = nan
> quiet_NaN () = nan
> ```
>
> The result on FreeBSD 10.1 64 bit (clang++ 3.4.1):
> ```
> stod ("nan") = nan
> stod ("-nan") = nan
> quiet_NaN () = nan
> ```
>
> Is it correct that returning negative NaN on Cygwin?
>
> Thanks.
>
> --
> 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
>


-- 
Stephen J Smoogen.

--
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

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: `std::stod ("nan")` returns negative NaN
  2018-08-13 16:53 ` Stephen John Smoogen
@ 2018-08-13 23:46   ` Duncan Roe
  2018-08-14  0:46     ` Stephen John Smoogen
  0 siblings, 1 reply; 32+ messages in thread
From: Duncan Roe @ 2018-08-13 23:46 UTC (permalink / raw)
  To: cygwin

On Mon, Aug 13, 2018 at 12:52:48PM -0400, Stephen John Smoogen wrote:
> On Mon, 13 Aug 2018 at 11:16, Masamichi Hosoda <trueroad@trueroad.jp> wrote:
[...]
> On Fedora 27 with 7.3.1 it gives
> ```
> stod ("nan") = nan
> stod ("-nan") = nan
> quiet_NaN () = nan
> ```
[...]

Same with Slackware 14.2 / gcc (GCC) 5.3.0

--
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

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: `std::stod ("nan")` returns negative NaN
  2018-08-13 23:46   ` Duncan Roe
@ 2018-08-14  0:46     ` Stephen John Smoogen
  2018-08-14  1:10       ` Masamichi Hosoda
  0 siblings, 1 reply; 32+ messages in thread
From: Stephen John Smoogen @ 2018-08-14  0:46 UTC (permalink / raw)
  To: cygwin

On Mon, 13 Aug 2018 at 19:46, Duncan Roe <duncan_roe@optusnet.com.au> wrote:
>
> On Mon, Aug 13, 2018 at 12:52:48PM -0400, Stephen John Smoogen wrote:
> > On Mon, 13 Aug 2018 at 11:16, Masamichi Hosoda <trueroad@trueroad.jp> wrote:
> [...]
> > On Fedora 27 with 7.3.1 it gives
> > ```
> > stod ("nan") = nan
> > stod ("-nan") = nan
> > quiet_NaN () = nan
> > ```
> [...]

I tested a compile on Windows Subsystem for Linux Ubuntu 18.04 which
had gcc 7.3.0. The output was the same as everything but Cygwin. At
this point it is time to pull through the gdb debugger and try to
figure out where it is coming from.


-- 
Stephen J Smoogen.

--
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

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: `std::stod ("nan")` returns negative NaN
  2018-08-14  0:46     ` Stephen John Smoogen
@ 2018-08-14  1:10       ` Masamichi Hosoda
  2018-08-14  2:31         ` strtod ("nan") returns negative NaN (was `std::stod ("nan")` returns negative NaN) Masamichi Hosoda
  0 siblings, 1 reply; 32+ messages in thread
From: Masamichi Hosoda @ 2018-08-14  1:10 UTC (permalink / raw)
  To: cygwin

> On Mon, 13 Aug 2018 at 19:46, Duncan Roe <duncan_roe@optusnet.com.au> wrote:
>>
>> On Mon, Aug 13, 2018 at 12:52:48PM -0400, Stephen John Smoogen wrote:
>> > On Mon, 13 Aug 2018 at 11:16, Masamichi Hosoda <trueroad@trueroad.jp> wrote:
>> [...]
>> > On Fedora 27 with 7.3.1 it gives
>> > ```
>> > stod ("nan") = nan
>> > stod ("-nan") = nan
>> > quiet_NaN () = nan
>> > ```
>> [...]
> 
> I tested a compile on Windows Subsystem for Linux Ubuntu 18.04 which
> had gcc 7.3.0. The output was the same as everything but Cygwin. At
> this point it is time to pull through the gdb debugger and try to
> figure out where it is coming from.

I suspect `cygwin1.dll`'s `strtod ()` etc.
Here's a code.

```
/* gcc foobar.c */

#include <math.h>
#include <stdio.h>
#include <stdlib.h>

int main (void)
{
  printf ("strtod (\"nan\", NULL) = %f\n", strtod ("nan", NULL));
  printf ("strtod (\"-nan\", NULL) = %f\n", strtod ("-nan", NULL));
  printf ("nan (\"\") = %f\n", nan (""));

  return 0;
}
```

Cygwin 2.10.0 64 bit with gcc 7.3.0
```
strtod ("nan", NULL) = -nan
strtod ("-nan", NULL) = nan
nan ("") = nan
```

Ubuntu 16.04 LTS 64 bit with gcc 5.4.0
```
strtod ("nan", NULL) = nan
strtod ("-nan", NULL) = nan
nan ("") = nan
```

--
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

^ permalink raw reply	[flat|nested] 32+ messages in thread

* strtod ("nan") returns negative NaN (was `std::stod ("nan")` returns negative NaN)
  2018-08-14  1:10       ` Masamichi Hosoda
@ 2018-08-14  2:31         ` Masamichi Hosoda
  2018-08-14  3:25           ` strtod ("nan") returns negative NaN Steven Penny
  2018-08-14  4:46           ` Masamichi Hosoda
  0 siblings, 2 replies; 32+ messages in thread
From: Masamichi Hosoda @ 2018-08-14  2:31 UTC (permalink / raw)
  To: cygwin; +Cc: trueroad

>> On Mon, 13 Aug 2018 at 19:46, Duncan Roe <duncan_roe@optusnet.com.au> wrote:
>>>
>>> On Mon, Aug 13, 2018 at 12:52:48PM -0400, Stephen John Smoogen wrote:
>>> > On Mon, 13 Aug 2018 at 11:16, Masamichi Hosoda <trueroad@trueroad.jp> wrote:
>>> [...]
>>> > On Fedora 27 with 7.3.1 it gives
>>> > ```
>>> > stod ("nan") = nan
>>> > stod ("-nan") = nan
>>> > quiet_NaN () = nan
>>> > ```
>>> [...]
>> 
>> I tested a compile on Windows Subsystem for Linux Ubuntu 18.04 which
>> had gcc 7.3.0. The output was the same as everything but Cygwin. At
>> this point it is time to pull through the gdb debugger and try to
>> figure out where it is coming from.
> 
> I suspect `cygwin1.dll`'s `strtod ()` etc.
> Here's a code.
> 
> ```
> /* gcc foobar.c */
> 
> #include <math.h>
> #include <stdio.h>
> #include <stdlib.h>
> 
> int main (void)
> {
>   printf ("strtod (\"nan\", NULL) = %f\n", strtod ("nan", NULL));
>   printf ("strtod (\"-nan\", NULL) = %f\n", strtod ("-nan", NULL));
>   printf ("nan (\"\") = %f\n", nan (""));
> 
>   return 0;
> }
> ```
> 
> Cygwin 2.10.0 64 bit with gcc 7.3.0
> ```
> strtod ("nan", NULL) = -nan
> strtod ("-nan", NULL) = nan
> nan ("") = nan
> ```
> 
> Ubuntu 16.04 LTS 64 bit with gcc 5.4.0
> ```
> strtod ("nan", NULL) = nan
> strtod ("-nan", NULL) = nan
> nan ("") = nan
> ```

If I understand correctly,
`std::stod ()` uses cygwin1.dll's `strtod ()` for the conversion.

`std::stod ()` is defined in
/usr/lib/gcc/x86_64-pc-cygwin/7.3.0/include/c++/bits/basic_string.h L6388-.
It calls `__gnu_cxx::__stoa ()` with pointer of `std::strtod ()`.

```
  inline double
  stod(const string& __str, size_t* __idx = 0)
  { return __gnu_cxx::__stoa(&std::strtod, "stod", __str.c_str(), __idx); }
```

`__gnu_cxx::__stoa ()` is defined in
/usr/lib/gcc/x86_64-pc-cygwin/7.3.0/include/c++/ext/string_conversions.h L51-.
It calls the first parameter, `std::strtod ()`.

`std::strtod ()` is cygwin1.dll's `strtod ()`.

--
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

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: strtod ("nan") returns negative NaN
  2018-08-14  2:31         ` strtod ("nan") returns negative NaN (was `std::stod ("nan")` returns negative NaN) Masamichi Hosoda
@ 2018-08-14  3:25           ` Steven Penny
  2018-08-14  4:46           ` Masamichi Hosoda
  1 sibling, 0 replies; 32+ messages in thread
From: Steven Penny @ 2018-08-14  3:25 UTC (permalink / raw)
  To: cygwin

On Tue, 14 Aug 2018 11:31:35, Masamichi Hosoda wrote:
> If I understand correctly,
> `std::stod ()` uses cygwin1.dll's `strtod ()` for the conversion.
>
> `std::stod ()` is defined in
> /usr/lib/gcc/x86_64-pc-cygwin/7.3.0/include/c++/bits/basic_string.h L6388-.
> It calls `__gnu_cxx::__stoa ()` with pointer of `std::strtod ()`.
>
> ```
>   inline double
>   stod(const string& __str, size_t* __idx = 0)
>   { return __gnu_cxx::__stoa(&std::strtod, "stod", __str.c_str(), __idx); }
> ```
>
> `__gnu_cxx::__stoa ()` is defined in
> /usr/lib/gcc/x86_64-pc-cygwin/7.3.0/include/c++/ext/string_conversions.h L51-.
> It calls the first parameter, `std::strtod ()`.
>
> `std::strtod ()` is cygwin1.dll's `strtod ()`.

Ah, so thats why this is happening:

    $ awk 'BEGIN {print +"nan"}'
    -nan

> the numeric value of the *numeric string* shall be the value that would be
> returned by the strtod() call

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/awk.html#tag_20_06_13_02


--
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

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: strtod ("nan") returns negative NaN
  2018-08-14  2:31         ` strtod ("nan") returns negative NaN (was `std::stod ("nan")` returns negative NaN) Masamichi Hosoda
  2018-08-14  3:25           ` strtod ("nan") returns negative NaN Steven Penny
@ 2018-08-14  4:46           ` Masamichi Hosoda
  2018-08-14  9:56             ` Corinna Vinschen
  1 sibling, 1 reply; 32+ messages in thread
From: Masamichi Hosoda @ 2018-08-14  4:46 UTC (permalink / raw)
  To: cygwin; +Cc: trueroad

[-- Attachment #1: Type: Text/Plain, Size: 961 bytes --]

>>> On Mon, 13 Aug 2018 at 19:46, Duncan Roe <duncan_roe@optusnet.com.au> wrote:
>>>>
>>>> On Mon, Aug 13, 2018 at 12:52:48PM -0400, Stephen John Smoogen wrote:
>>>> > On Mon, 13 Aug 2018 at 11:16, Masamichi Hosoda <trueroad@trueroad.jp> wrote:
>>>> [...]
>>>> > On Fedora 27 with 7.3.1 it gives
>>>> > ```
>>>> > stod ("nan") = nan
>>>> > stod ("-nan") = nan
>>>> > quiet_NaN () = nan
>>>> > ```
[...]
>> Cygwin 2.10.0 64 bit with gcc 7.3.0
>> ```
>> strtod ("nan", NULL) = -nan
>> strtod ("-nan", NULL) = nan
>> nan ("") = nan
>> ```
>> 
>> Ubuntu 16.04 LTS 64 bit with gcc 5.4.0
>> ```
>> strtod ("nan", NULL) = nan
>> strtod ("-nan", NULL) = nan
>> nan ("") = nan
>> ```

I've created the quick hack patch that fixes `strtod ()`.

On Cygwin 64 bit with the patch, result of foobar.c:

```
strtod ("nan", NULL) = nan
strtod ("-nan", NULL) = nan
nan ("") = nan
```

Also result of foobar.cc:

```
stod ("nan") = nan
stod ("-nan") = nan
quiet_NaN () = nan
```

[-- Attachment #2: 0001-Fix-strtod-nan-returns-qNaN.patch --]
[-- Type: Text/X-Patch, Size: 1758 bytes --]

From a50ee5a4747a99c70469a53fe959f3dc22d3b79a Mon Sep 17 00:00:00 2001
From: Masamichi Hosoda <trueroad@trueroad.jp>
Date: Tue, 14 Aug 2018 12:50:32 +0900
Subject: [PATCH] Fix strtod ("nan") returns qNaN

The definition of qNaN for x86_64 and x86 was wrong.
So strtod ("nan") returned sNaN instead of qNaN.

Furthermore, it was inverted the sign bit with the presence of `-` character.
So strtod ("-nan") returned qNaN.

This commit fixes definition of qNaN
and removes the sign bit inversion when evaluating "nan".
---
 newlib/libc/stdlib/gd_qnan.h | 8 ++++----
 newlib/libc/stdlib/strtod.c  | 1 +
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/newlib/libc/stdlib/gd_qnan.h b/newlib/libc/stdlib/gd_qnan.h
index b775f82..3ca337b 100644
--- a/newlib/libc/stdlib/gd_qnan.h
+++ b/newlib/libc/stdlib/gd_qnan.h
@@ -26,18 +26,18 @@
 #elif defined(__IEEE_LITTLE_ENDIAN)
 
 #if !defined(__mips)
-#define f_QNAN 0xffc00000
+#define f_QNAN 0x7fc00000
 #define d_QNAN0 0x0
-#define d_QNAN1 0xfff80000
+#define d_QNAN1 0x7ff80000
 #define ld_QNAN0 0x0
 #define ld_QNAN1 0xc0000000
-#define ld_QNAN2 0xffff
+#define ld_QNAN2 0x7fff
 #define ld_QNAN3 0x0
 #define ldus_QNAN0 0x0
 #define ldus_QNAN1 0x0
 #define ldus_QNAN2 0x0
 #define ldus_QNAN3 0xc000
-#define ldus_QNAN4 0xffff
+#define ldus_QNAN4 0x7fff
 #elif defined(__mips_nan2008)
 #define f_QNAN 0x7fc00000
 #define d_QNAN0 0x0
diff --git a/newlib/libc/stdlib/strtod.c b/newlib/libc/stdlib/strtod.c
index 0cfa9e6..3b9fd26 100644
--- a/newlib/libc/stdlib/strtod.c
+++ b/newlib/libc/stdlib/strtod.c
@@ -451,6 +451,7 @@ _strtod_l (struct _reent *ptr, const char *__restrict s00, char **__restrict se,
 #ifndef No_Hex_NaN
 						}
 #endif
+					sign = 0;
 					goto ret;
 					}
 			  }
-- 
2.17.0



[-- Attachment #3: Type: text/plain, Size: 219 bytes --]


--
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

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: strtod ("nan") returns negative NaN
  2018-08-14  4:46           ` Masamichi Hosoda
@ 2018-08-14  9:56             ` Corinna Vinschen
  2018-08-14 10:39               ` Corinna Vinschen
  2018-08-14 15:05               ` Masamichi Hosoda
  0 siblings, 2 replies; 32+ messages in thread
From: Corinna Vinschen @ 2018-08-14  9:56 UTC (permalink / raw)
  To: cygwin

[-- Attachment #1: Type: text/plain, Size: 1156 bytes --]

On Aug 14 13:45, Masamichi Hosoda wrote:
> >From a50ee5a4747a99c70469a53fe959f3dc22d3b79a Mon Sep 17 00:00:00 2001
> From: Masamichi Hosoda <trueroad@trueroad.jp>
> Date: Tue, 14 Aug 2018 12:50:32 +0900
> Subject: [PATCH] Fix strtod ("nan") returns qNaN
> 
> The definition of qNaN for x86_64 and x86 was wrong.
> So strtod ("nan") returned sNaN instead of qNaN.
> 
> Furthermore, it was inverted the sign bit with the presence of `-` character.
> So strtod ("-nan") returned qNaN.
> 
> This commit fixes definition of qNaN
> and removes the sign bit inversion when evaluating "nan".
> ---
>  newlib/libc/stdlib/gd_qnan.h | 8 ++++----
>  newlib/libc/stdlib/strtod.c  | 1 +
>  2 files changed, 5 insertions(+), 4 deletions(-)

Can you please send this patch to the newlib AT sourceware DOT org
mailing list?  As soon as something in newlib gets changed, a lot of
other targets are affected and the guys working on those targets should
have a chance to chime in.


Thanks,
Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Maintainer                 cygwin AT cygwin DOT com
Red Hat

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: strtod ("nan") returns negative NaN
  2018-08-14  9:56             ` Corinna Vinschen
@ 2018-08-14 10:39               ` Corinna Vinschen
  2018-08-14 12:18                 ` Masamichi Hosoda
  2018-08-14 19:44                 ` Achim Gratz
  2018-08-14 15:05               ` Masamichi Hosoda
  1 sibling, 2 replies; 32+ messages in thread
From: Corinna Vinschen @ 2018-08-14 10:39 UTC (permalink / raw)
  To: cygwin

[-- Attachment #1: Type: text/plain, Size: 2143 bytes --]

On Aug 14 11:56, Corinna Vinschen wrote:
> On Aug 14 13:45, Masamichi Hosoda wrote:
> > >From a50ee5a4747a99c70469a53fe959f3dc22d3b79a Mon Sep 17 00:00:00 2001
> > From: Masamichi Hosoda <trueroad@trueroad.jp>
> > Date: Tue, 14 Aug 2018 12:50:32 +0900
> > Subject: [PATCH] Fix strtod ("nan") returns qNaN
> > 
> > The definition of qNaN for x86_64 and x86 was wrong.
> > So strtod ("nan") returned sNaN instead of qNaN.
> > 
> > Furthermore, it was inverted the sign bit with the presence of `-` character.
> > So strtod ("-nan") returned qNaN.
> > 
> > This commit fixes definition of qNaN
> > and removes the sign bit inversion when evaluating "nan".
> > ---
> >  newlib/libc/stdlib/gd_qnan.h | 8 ++++----
> >  newlib/libc/stdlib/strtod.c  | 1 +
> >  2 files changed, 5 insertions(+), 4 deletions(-)
> 
> Can you please send this patch to the newlib AT sourceware DOT org
> mailing list?  As soon as something in newlib gets changed, a lot of
> other targets are affected and the guys working on those targets should
> have a chance to chime in.

Looks like strtold is affected as well, just differently:

  printf ("strtod (\"nan\", NULL) = %f\n", strtod ("nan", NULL));
  printf ("strtod (\"-nan\", NULL) = %f\n", strtod ("-nan", NULL));
  printf ("strtold (\"nan\", NULL) = %Lf\n", strtold ("nan", NULL));
  printf ("strtold (\"-nan\", NULL) = %Lf\n", strtold ("-nan", NULL));
  printf ("nan (\"\") = %f\n", nan (""));

==>

  strtod ("nan", NULL) = -nan
  strtod ("-nan", NULL) = nan
  strtold ("nan", NULL) = -nan
  strtold ("-nan", NULL) = -nan
  nan ("") = nan

so it prints always -nan.

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?


Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Maintainer                 cygwin AT cygwin DOT com
Red Hat

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: strtod ("nan") returns negative NaN
  2018-08-14 10:39               ` Corinna Vinschen
@ 2018-08-14 12:18                 ` Masamichi Hosoda
  2018-08-14 13:23                   ` Corinna Vinschen
  2018-08-14 19:44                 ` Achim Gratz
  1 sibling, 1 reply; 32+ messages in thread
From: Masamichi Hosoda @ 2018-08-14 12:18 UTC (permalink / raw)
  To: cygwin; +Cc: trueroad

> On Aug 14 11:56, Corinna Vinschen wrote:
>> On Aug 14 13:45, Masamichi Hosoda wrote:
>> > >From a50ee5a4747a99c70469a53fe959f3dc22d3b79a Mon Sep 17 00:00:00 2001
>> > From: Masamichi Hosoda <trueroad@trueroad.jp>
>> > Date: Tue, 14 Aug 2018 12:50:32 +0900
>> > Subject: [PATCH] Fix strtod ("nan") returns qNaN
>> > 
>> > The definition of qNaN for x86_64 and x86 was wrong.
>> > So strtod ("nan") returned sNaN instead of qNaN.
>> > 
>> > Furthermore, it was inverted the sign bit with the presence of `-` character.
>> > So strtod ("-nan") returned qNaN.
>> > 
>> > This commit fixes definition of qNaN
>> > and removes the sign bit inversion when evaluating "nan".
>> > ---
>> >  newlib/libc/stdlib/gd_qnan.h | 8 ++++----
>> >  newlib/libc/stdlib/strtod.c  | 1 +
>> >  2 files changed, 5 insertions(+), 4 deletions(-)
>> 
>> Can you please send this patch to the newlib AT sourceware DOT org
>> mailing list?  As soon as something in newlib gets changed, a lot of
>> other targets are affected and the guys working on those targets should
>> have a chance to chime in.

I'll improve the patch and send it.
It did not consider environments excluding x86 and x86_64.

> Looks like strtold is affected as well, just differently:
> 
>   printf ("strtod (\"nan\", NULL) = %f\n", strtod ("nan", NULL));
>   printf ("strtod (\"-nan\", NULL) = %f\n", strtod ("-nan", NULL));
>   printf ("strtold (\"nan\", NULL) = %Lf\n", strtold ("nan", NULL));
>   printf ("strtold (\"-nan\", NULL) = %Lf\n", strtold ("-nan", NULL));
>   printf ("nan (\"\") = %f\n", nan (""));
> 
> ==>
> 
>   strtod ("nan", NULL) = -nan
>   strtod ("-nan", NULL) = nan
>   strtold ("nan", NULL) = -nan
>   strtold ("-nan", NULL) = -nan
>   nan ("") = nan
> 
> so it prints always -nan.
> 
> 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.

My previous patch removes the sign inversion in strtod when NaN.
But I did not fix strtold.

Perhaps, the following patch removes the sign bit setting of strtold when NaN.

```
--- a/newlib/libc/stdlib/strtodg.c
+++ b/newlib/libc/stdlib/strtodg.c
@@ -585,6 +585,7 @@ _strtodg_l (struct _reent *p, const char *s00, char **se, FPI *fpi, Long *exp,
 					if (*s == '(') /*)*/
 						irv = hexnan(&s, fpi, bits);
 #endif
+					sign = 0;
 					goto infnanexp;
 					}
 			  }
```

--
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

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: strtod ("nan") returns negative NaN
  2018-08-14 12:18                 ` Masamichi Hosoda
@ 2018-08-14 13:23                   ` Corinna Vinschen
  2018-08-14 13:41                     ` Stephen John Smoogen
                                       ` (3 more replies)
  0 siblings, 4 replies; 32+ messages in thread
From: Corinna Vinschen @ 2018-08-14 13:23 UTC (permalink / raw)
  To: cygwin

[-- Attachment #1: Type: text/plain, Size: 2474 bytes --]

On Aug 14 21:17, Masamichi Hosoda wrote:
> > On Aug 14 11:56, Corinna Vinschen wrote:
> >> On Aug 14 13:45, Masamichi Hosoda wrote:
> >> > >From a50ee5a4747a99c70469a53fe959f3dc22d3b79a Mon Sep 17 00:00:00 2001
> >> > From: Masamichi Hosoda <trueroad@trueroad.jp>
> >> > Date: Tue, 14 Aug 2018 12:50:32 +0900
> >> > Subject: [PATCH] Fix strtod ("nan") returns qNaN
> >> > 
> >> > The definition of qNaN for x86_64 and x86 was wrong.
> >> > So strtod ("nan") returned sNaN instead of qNaN.
> >> > 
> >> > Furthermore, it was inverted the sign bit with the presence of `-` character.
> >> > So strtod ("-nan") returned qNaN.
> >> > 
> >> > This commit fixes definition of qNaN
> >> > and removes the sign bit inversion when evaluating "nan".
> >> > ---
> >> >  newlib/libc/stdlib/gd_qnan.h | 8 ++++----
> >> >  newlib/libc/stdlib/strtod.c  | 1 +
> >> >  2 files changed, 5 insertions(+), 4 deletions(-)
> >> [...]
> > 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

?

Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Maintainer                 cygwin AT cygwin DOT com
Red Hat

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: strtod ("nan") returns negative NaN
  2018-08-14 13:23                   ` Corinna Vinschen
@ 2018-08-14 13:41                     ` Stephen John Smoogen
  2018-08-14 15:25                     ` Heavenly Avenger
                                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 32+ messages in thread
From: Stephen John Smoogen @ 2018-08-14 13:41 UTC (permalink / raw)
  To: cygwin

On Tue, 14 Aug 2018 at 09:23, Corinna Vinschen
<corinna-cygwin@cygwin.com> wrote:
>
> On Aug 14 21:17, Masamichi Hosoda wrote:
> > > On Aug 14 11:56, Corinna Vinschen wrote:
> > >> On Aug 14 13:45, Masamichi Hosoda wrote:
> > >> > >From a50ee5a4747a99c70469a53fe959f3dc22d3b79a Mon Sep 17 00:00:00 2001
> > >> > From: Masamichi Hosoda <trueroad@trueroad.jp>
> > >> > Date: Tue, 14 Aug 2018 12:50:32 +0900
> > >> > Subject: [PATCH] Fix strtod ("nan") returns qNaN
> > >> >
> > >> > The definition of qNaN for x86_64 and x86 was wrong.
> > >> > So strtod ("nan") returned sNaN instead of qNaN.
> > >> >
> > >> > Furthermore, it was inverted the sign bit with the presence of `-` character.
> > >> > So strtod ("-nan") returned qNaN.
> > >> >
> > >> > This commit fixes definition of qNaN
> > >> > and removes the sign bit inversion when evaluating "nan".
> > >> > ---
> > >> >  newlib/libc/stdlib/gd_qnan.h | 8 ++++----
> > >> >  newlib/libc/stdlib/strtod.c  | 1 +
> > >> >  2 files changed, 5 insertions(+), 4 deletions(-)
> > >> [...]
> > > 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
>
> ?

This is going off some old memories from dealing with this looong ago
with Linux. I think that is set in the IEEE standard where there is
only a NaN and it is neither negative or positive.. it is just NaN.
While Negative NaN is possible, it is implementation defined and most
implementations seem to now default to the if you see -nan 'something
weird has happened'. I don't have access to the emails where this came
up years ago.. so I found these which might help

https://en.wikipedia.org/wiki/IEEE_754
https://en.wikipedia.org/wiki/NaN
http://www.cplusplus.com/forum/general/73201/



-- 
Stephen J Smoogen.

--
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

^ permalink raw reply	[flat|nested] 32+ messages in thread

* strtod ("nan") returns negative NaN
  2018-08-14  9:56             ` Corinna Vinschen
  2018-08-14 10:39               ` Corinna Vinschen
@ 2018-08-14 15:05               ` Masamichi Hosoda
  2018-08-14 15:21                 ` Masamichi Hosoda
                                   ` (2 more replies)
  1 sibling, 3 replies; 32+ messages in thread
From: Masamichi Hosoda @ 2018-08-14 15:05 UTC (permalink / raw)
  To: newlib; +Cc: cygwin, corinna-cygwin, trueroad

[-- Attachment #1: Type: Text/Plain, Size: 1702 bytes --]

Hi

I've found that strtod ("nan") returns negative NaN on Cygwin 64 bit.
https://cygwin.com/ml/cygwin/2018-08/msg00168.html

On Linux with glibc, both strtod ("nan")
and strtod ("-nan") return positive NaN.

So I've created the patch that behaves like glibc.
Both strtod ("nan") and strtod ("-nan") return positive NaN.

Sample code:
```
#include <stdio.h>
#include <stdlib.h>

int main (void)
{
  printf ("strtof (\"nan\", NULL) = %f\n", strtof ("nan", NULL));
  printf ("strtof (\"-nan\", NULL) = %f\n", strtof ("-nan", NULL));
  printf ("strtod (\"nan\", NULL) = %f\n", strtod ("nan", NULL));
  printf ("strtod (\"-nan\", NULL) = %f\n", strtod ("-nan", NULL));
  printf ("strtold (\"nan\", NULL) = %Lf\n", strtold ("nan", NULL));
  printf ("strtold (\"-nan\", NULL) = %Lf\n", strtold ("-nan", NULL));
}
```

The result of Cygwin (newlib) without my patch:
```
strtof ("nan", NULL) = nan
strtof ("-nan", NULL) = nan
strtod ("nan", NULL) = -nan
strtod ("-nan", NULL) = nan
strtold ("nan", NULL) = -nan
strtold ("-nan", NULL) = -nan
```

The result of Linux (glibc, Ubuntu 16.04):
```
strtof ("nan", NULL) = nan
strtof ("-nan", NULL) = nan
strtod ("nan", NULL) = nan
strtod ("-nan", NULL) = nan
strtold ("nan", NULL) = nan
strtold ("-nan", NULL) = nan
```

The result of FreeBSD 10.1 (BSD libc):
```
strtof ("nan", NULL) = nan
strtof ("-nan", NULL) = nan
strtod ("nan", NULL) = nan
strtod ("-nan", NULL) = nan
strtold ("nan", NULL) = nan
strtold ("-nan", NULL) = nan
```

The result of Cygwin (newlib) with my patch:
```
strtof ("nan", NULL) = nan
strtof ("-nan", NULL) = nan
strtod ("nan", NULL) = nan
strtod ("-nan", NULL) = nan
strtold ("nan", NULL) = nan
strtold ("-nan", NULL) = nan
```

Thanks.

[-- Attachment #2: 0001-Fix-strtod-nan-returns-negative-NaN.patch --]
[-- Type: Text/X-Patch, Size: 1512 bytes --]

From 91cf4a20e0773f4a38d6d56b0867fe3725859e5e Mon Sep 17 00:00:00 2001
From: Masamichi Hosoda <trueroad@trueroad.jp>
Date: Tue, 14 Aug 2018 22:29:34 +0900
Subject: [PATCH 1/2] Fix strtod ("nan") returns negative NaN

The definition of qNaN for x86_64 and i386 was wrong.
So strtod ("nan") and strtold ("nan") returned negative NaN
instead of positive NaN.

strtof ("nan") returns positive NaN so it does not have this issue.

This commit fixes definition of qNaN for x86_64 and i386.
So strtod ("nan") and strtold ("nan") return positive NaN.
---
 newlib/libc/stdlib/gd_qnan.h | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/newlib/libc/stdlib/gd_qnan.h b/newlib/libc/stdlib/gd_qnan.h
index b775f82..8b0726a 100644
--- a/newlib/libc/stdlib/gd_qnan.h
+++ b/newlib/libc/stdlib/gd_qnan.h
@@ -26,6 +26,20 @@
 #elif defined(__IEEE_LITTLE_ENDIAN)
 
 #if !defined(__mips)
+#if defined (__x86_64__) || defined (__i386__)
+#define f_QNAN 0x7fc00000
+#define d_QNAN0 0x0
+#define d_QNAN1 0x7ff80000
+#define ld_QNAN0 0x0
+#define ld_QNAN1 0xc0000000
+#define ld_QNAN2 0x7fff
+#define ld_QNAN3 0x0
+#define ldus_QNAN0 0x0
+#define ldus_QNAN1 0x0
+#define ldus_QNAN2 0x0
+#define ldus_QNAN3 0xc000
+#define ldus_QNAN4 0x7fff
+#else
 #define f_QNAN 0xffc00000
 #define d_QNAN0 0x0
 #define d_QNAN1 0xfff80000
@@ -38,6 +52,7 @@
 #define ldus_QNAN2 0x0
 #define ldus_QNAN3 0xc000
 #define ldus_QNAN4 0xffff
+#endif
 #elif defined(__mips_nan2008)
 #define f_QNAN 0x7fc00000
 #define d_QNAN0 0x0
-- 
2.17.0


[-- Attachment #3: 0002-Fix-strtod-nan-returns-negative-NaN.patch --]
[-- Type: Text/X-Patch, Size: 1646 bytes --]

From 7256702e5034b016b5114dd1a6c4c1a689a17816 Mon Sep 17 00:00:00 2001
From: Masamichi Hosoda <trueroad@trueroad.jp>
Date: Tue, 14 Aug 2018 23:12:49 +0900
Subject: [PATCH 2/2] Fix strtod ("-nan") returns negative NaN

On Linux,
glibc's strtod ("-nan") and strtold ("-nan") return positive NaN.

But, newlib's strtod ("-nan") returns negative NaN
because it inverted the sign with the presence of `-` character.
And, newlib's srtold ("-nan") returns negative NaN
because it set the sign bit with the presence of `-` character.

newlib's strtof ("-nan") returns positive NaN same as Linux glibc's.

This commit removes strtod's NaN sign inversion
and removes strtold's NaN sign bit setting.
So strtod ("-nan") and strtold ("-nan") return positive NaN
same as Linux glibc.
---
 newlib/libc/stdlib/strtod.c  | 1 +
 newlib/libc/stdlib/strtodg.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/newlib/libc/stdlib/strtod.c b/newlib/libc/stdlib/strtod.c
index 0cfa9e6..3b9fd26 100644
--- a/newlib/libc/stdlib/strtod.c
+++ b/newlib/libc/stdlib/strtod.c
@@ -451,6 +451,7 @@ _strtod_l (struct _reent *ptr, const char *__restrict s00, char **__restrict se,
 #ifndef No_Hex_NaN
 						}
 #endif
+					sign = 0;
 					goto ret;
 					}
 			  }
diff --git a/newlib/libc/stdlib/strtodg.c b/newlib/libc/stdlib/strtodg.c
index 4ac1f8e..cc2842b 100644
--- a/newlib/libc/stdlib/strtodg.c
+++ b/newlib/libc/stdlib/strtodg.c
@@ -585,6 +585,7 @@ _strtodg_l (struct _reent *p, const char *s00, char **se, FPI *fpi, Long *exp,
 					if (*s == '(') /*)*/
 						irv = hexnan(&s, fpi, bits);
 #endif
+					sign = 0;
 					goto infnanexp;
 					}
 			  }
-- 
2.17.0



[-- Attachment #4: Type: text/plain, Size: 219 bytes --]


--
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

^ permalink raw reply	[flat|nested] 32+ messages in thread

* strtod ("nan") returns negative NaN
  2018-08-14 15:05               ` Masamichi Hosoda
@ 2018-08-14 15:21                 ` Masamichi Hosoda
  2018-08-14 15:35                 ` Heavenly Avenger
  2018-08-14 20:05                 ` Joseph Myers
  2 siblings, 0 replies; 32+ messages in thread
From: Masamichi Hosoda @ 2018-08-14 15:21 UTC (permalink / raw)
  To: newlib; +Cc: cygwin, corinna-cygwin, trueroad

[-- Attachment #1: Type: Text/Plain, Size: 1702 bytes --]

Hi

I've found that strtod ("nan") returns negative NaN on Cygwin 64 bit.
https://cygwin.com/ml/cygwin/2018-08/msg00168.html

On Linux with glibc, both strtod ("nan")
and strtod ("-nan") return positive NaN.

So I've created the patch that behaves like glibc.
Both strtod ("nan") and strtod ("-nan") return positive NaN.

Sample code:
```
#include <stdio.h>
#include <stdlib.h>

int main (void)
{
  printf ("strtof (\"nan\", NULL) = %f\n", strtof ("nan", NULL));
  printf ("strtof (\"-nan\", NULL) = %f\n", strtof ("-nan", NULL));
  printf ("strtod (\"nan\", NULL) = %f\n", strtod ("nan", NULL));
  printf ("strtod (\"-nan\", NULL) = %f\n", strtod ("-nan", NULL));
  printf ("strtold (\"nan\", NULL) = %Lf\n", strtold ("nan", NULL));
  printf ("strtold (\"-nan\", NULL) = %Lf\n", strtold ("-nan", NULL));
}
```

The result of Cygwin (newlib) without my patch:
```
strtof ("nan", NULL) = nan
strtof ("-nan", NULL) = nan
strtod ("nan", NULL) = -nan
strtod ("-nan", NULL) = nan
strtold ("nan", NULL) = -nan
strtold ("-nan", NULL) = -nan
```

The result of Linux (glibc, Ubuntu 16.04):
```
strtof ("nan", NULL) = nan
strtof ("-nan", NULL) = nan
strtod ("nan", NULL) = nan
strtod ("-nan", NULL) = nan
strtold ("nan", NULL) = nan
strtold ("-nan", NULL) = nan
```

The result of FreeBSD 10.1 (BSD libc):
```
strtof ("nan", NULL) = nan
strtof ("-nan", NULL) = nan
strtod ("nan", NULL) = nan
strtod ("-nan", NULL) = nan
strtold ("nan", NULL) = nan
strtold ("-nan", NULL) = nan
```

The result of Cygwin (newlib) with my patch:
```
strtof ("nan", NULL) = nan
strtof ("-nan", NULL) = nan
strtod ("nan", NULL) = nan
strtod ("-nan", NULL) = nan
strtold ("nan", NULL) = nan
strtold ("-nan", NULL) = nan
```

Thanks.

[-- Attachment #2: 0001-Fix-strtod-nan-returns-negative-NaN.patch --]
[-- Type: Text/X-Patch, Size: 1512 bytes --]

From 91cf4a20e0773f4a38d6d56b0867fe3725859e5e Mon Sep 17 00:00:00 2001
From: Masamichi Hosoda <trueroad@trueroad.jp>
Date: Tue, 14 Aug 2018 22:29:34 +0900
Subject: [PATCH 1/2] Fix strtod ("nan") returns negative NaN

The definition of qNaN for x86_64 and i386 was wrong.
So strtod ("nan") and strtold ("nan") returned negative NaN
instead of positive NaN.

strtof ("nan") returns positive NaN so it does not have this issue.

This commit fixes definition of qNaN for x86_64 and i386.
So strtod ("nan") and strtold ("nan") return positive NaN.
---
 newlib/libc/stdlib/gd_qnan.h | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/newlib/libc/stdlib/gd_qnan.h b/newlib/libc/stdlib/gd_qnan.h
index b775f82..8b0726a 100644
--- a/newlib/libc/stdlib/gd_qnan.h
+++ b/newlib/libc/stdlib/gd_qnan.h
@@ -26,6 +26,20 @@
 #elif defined(__IEEE_LITTLE_ENDIAN)
 
 #if !defined(__mips)
+#if defined (__x86_64__) || defined (__i386__)
+#define f_QNAN 0x7fc00000
+#define d_QNAN0 0x0
+#define d_QNAN1 0x7ff80000
+#define ld_QNAN0 0x0
+#define ld_QNAN1 0xc0000000
+#define ld_QNAN2 0x7fff
+#define ld_QNAN3 0x0
+#define ldus_QNAN0 0x0
+#define ldus_QNAN1 0x0
+#define ldus_QNAN2 0x0
+#define ldus_QNAN3 0xc000
+#define ldus_QNAN4 0x7fff
+#else
 #define f_QNAN 0xffc00000
 #define d_QNAN0 0x0
 #define d_QNAN1 0xfff80000
@@ -38,6 +52,7 @@
 #define ldus_QNAN2 0x0
 #define ldus_QNAN3 0xc000
 #define ldus_QNAN4 0xffff
+#endif
 #elif defined(__mips_nan2008)
 #define f_QNAN 0x7fc00000
 #define d_QNAN0 0x0
-- 
2.17.0


[-- Attachment #3: 0002-Fix-strtod-nan-returns-negative-NaN.patch --]
[-- Type: Text/X-Patch, Size: 1646 bytes --]

From 7256702e5034b016b5114dd1a6c4c1a689a17816 Mon Sep 17 00:00:00 2001
From: Masamichi Hosoda <trueroad@trueroad.jp>
Date: Tue, 14 Aug 2018 23:12:49 +0900
Subject: [PATCH 2/2] Fix strtod ("-nan") returns negative NaN

On Linux,
glibc's strtod ("-nan") and strtold ("-nan") return positive NaN.

But, newlib's strtod ("-nan") returns negative NaN
because it inverted the sign with the presence of `-` character.
And, newlib's srtold ("-nan") returns negative NaN
because it set the sign bit with the presence of `-` character.

newlib's strtof ("-nan") returns positive NaN same as Linux glibc's.

This commit removes strtod's NaN sign inversion
and removes strtold's NaN sign bit setting.
So strtod ("-nan") and strtold ("-nan") return positive NaN
same as Linux glibc.
---
 newlib/libc/stdlib/strtod.c  | 1 +
 newlib/libc/stdlib/strtodg.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/newlib/libc/stdlib/strtod.c b/newlib/libc/stdlib/strtod.c
index 0cfa9e6..3b9fd26 100644
--- a/newlib/libc/stdlib/strtod.c
+++ b/newlib/libc/stdlib/strtod.c
@@ -451,6 +451,7 @@ _strtod_l (struct _reent *ptr, const char *__restrict s00, char **__restrict se,
 #ifndef No_Hex_NaN
 						}
 #endif
+					sign = 0;
 					goto ret;
 					}
 			  }
diff --git a/newlib/libc/stdlib/strtodg.c b/newlib/libc/stdlib/strtodg.c
index 4ac1f8e..cc2842b 100644
--- a/newlib/libc/stdlib/strtodg.c
+++ b/newlib/libc/stdlib/strtodg.c
@@ -585,6 +585,7 @@ _strtodg_l (struct _reent *p, const char *s00, char **se, FPI *fpi, Long *exp,
 					if (*s == '(') /*)*/
 						irv = hexnan(&s, fpi, bits);
 #endif
+					sign = 0;
 					goto infnanexp;
 					}
 			  }
-- 
2.17.0



[-- Attachment #4: Type: text/plain, Size: 219 bytes --]


--
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

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: strtod ("nan") returns negative NaN
  2018-08-14 13:23                   ` Corinna Vinschen
  2018-08-14 13:41                     ` Stephen John Smoogen
@ 2018-08-14 15:25                     ` Heavenly Avenger
  2018-08-14 15:54                       ` Corinna Vinschen
  2018-08-14 16:05                     ` Masamichi Hosoda
  2018-08-14 19:24                     ` Steven Penny
  3 siblings, 1 reply; 32+ messages in thread
From: Heavenly Avenger @ 2018-08-14 15:25 UTC (permalink / raw)
  To: cygwin

On 8/14/2018 10:23 AM, Corinna Vinschen wrote:
> On Aug 14 21:17, Masamichi Hosoda wrote:
>>> On Aug 14 11:56, Corinna Vinschen wrote:
>>>> On Aug 14 13:45, Masamichi Hosoda wrote:
>>>>> >From a50ee5a4747a99c70469a53fe959f3dc22d3b79a Mon Sep 17 00:00:00 2001
>>>>> From: Masamichi Hosoda <trueroad@trueroad.jp>
>>>>> Date: Tue, 14 Aug 2018 12:50:32 +0900
>>>>> Subject: [PATCH] Fix strtod ("nan") returns qNaN
>>>>>
>>>>> The definition of qNaN for x86_64 and x86 was wrong.
>>>>> So strtod ("nan") returned sNaN instead of qNaN.
>>>>>
>>>>> Furthermore, it was inverted the sign bit with the presence of `-` character.
>>>>> So strtod ("-nan") returned qNaN.
>>>>>
>>>>> This commit fixes definition of qNaN
>>>>> and removes the sign bit inversion when evaluating "nan".
>>>>> ---
>>>>>   newlib/libc/stdlib/gd_qnan.h | 8 ++++----
>>>>>   newlib/libc/stdlib/strtod.c  | 1 +
>>>>>   2 files changed, 5 insertions(+), 4 deletions(-)
>>>> [...]
>>> 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
>
> ?
>
> Corinna
>
I'd say it is not the better/best approach as, even though it makes 
sense, all other implementations or linux distributions treat it as a 
plain "nan". So anything written for linux will potentially break on 
cygwin, I am not sure this is the idea behind cygwin, right?

Besides, it only adds complexity when checking for nans, if string 
comparison is relied upon, as an additional character may show up.

As NaN is essentially not a number, what is not a number can't be said 
as positive or negative. Then we get to a whole philosophical level. It 
can, but we can't guarantee a cow (which is not a number) can be seen 
with a "positive cow". A mood (which is not a number), can be seen as 
positive or negative. Yet it will depend on your concept of a positive 
or negative mood... so... well, better not leave the algebra sign to 
this. As 0 is equal to -0. Does -0 exist? :)

--
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

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: strtod ("nan") returns negative NaN
  2018-08-14 15:05               ` Masamichi Hosoda
  2018-08-14 15:21                 ` Masamichi Hosoda
@ 2018-08-14 15:35                 ` Heavenly Avenger
  2018-08-14 20:05                 ` Joseph Myers
  2 siblings, 0 replies; 32+ messages in thread
From: Heavenly Avenger @ 2018-08-14 15:35 UTC (permalink / raw)
  To: cygwin

Here's the result for a gentoo with the same code provided by Masamichi 
Hosoda.

Linux ethereal 4.14.32-std522-amd64 #2 SMP Sat Mar 31 20:05:28 UTC 2018 
x86_64 Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz GenuineIntel GNU/Linux

strtof ("nan", NULL) = nan
strtof ("-nan", NULL) = nan
strtod ("nan", NULL) = nan
strtod ("-nan", NULL) = nan
strtold ("nan", NULL) = nan
strtold ("-nan", NULL) = nan

This further supports the reasoning to always return just 'nan'.


On 8/14/2018 12:05 PM, Masamichi Hosoda wrote:
> Hi
>
> I've found that strtod ("nan") returns negative NaN on Cygwin 64 bit.
> https://cygwin.com/ml/cygwin/2018-08/msg00168.html
>
> On Linux with glibc, both strtod ("nan")
> and strtod ("-nan") return positive NaN.
>
> So I've created the patch that behaves like glibc.
> Both strtod ("nan") and strtod ("-nan") return positive NaN.
>
> Sample code:
> ```
> #include <stdio.h>
> #include <stdlib.h>
>
> int main (void)
> {
>    printf ("strtof (\"nan\", NULL) = %f\n", strtof ("nan", NULL));
>    printf ("strtof (\"-nan\", NULL) = %f\n", strtof ("-nan", NULL));
>    printf ("strtod (\"nan\", NULL) = %f\n", strtod ("nan", NULL));
>    printf ("strtod (\"-nan\", NULL) = %f\n", strtod ("-nan", NULL));
>    printf ("strtold (\"nan\", NULL) = %Lf\n", strtold ("nan", NULL));
>    printf ("strtold (\"-nan\", NULL) = %Lf\n", strtold ("-nan", NULL));
> }
> ```
>
> The result of Cygwin (newlib) without my patch:
> ```
> strtof ("nan", NULL) = nan
> strtof ("-nan", NULL) = nan
> strtod ("nan", NULL) = -nan
> strtod ("-nan", NULL) = nan
> strtold ("nan", NULL) = -nan
> strtold ("-nan", NULL) = -nan
> ```
>
> The result of Linux (glibc, Ubuntu 16.04):
> ```
> strtof ("nan", NULL) = nan
> strtof ("-nan", NULL) = nan
> strtod ("nan", NULL) = nan
> strtod ("-nan", NULL) = nan
> strtold ("nan", NULL) = nan
> strtold ("-nan", NULL) = nan
> ```
>
> The result of FreeBSD 10.1 (BSD libc):
> ```
> strtof ("nan", NULL) = nan
> strtof ("-nan", NULL) = nan
> strtod ("nan", NULL) = nan
> strtod ("-nan", NULL) = nan
> strtold ("nan", NULL) = nan
> strtold ("-nan", NULL) = nan
> ```
>
> The result of Cygwin (newlib) with my patch:
> ```
> strtof ("nan", NULL) = nan
> strtof ("-nan", NULL) = nan
> strtod ("nan", NULL) = nan
> strtod ("-nan", NULL) = nan
> strtold ("nan", NULL) = nan
> strtold ("-nan", NULL) = nan
> ```
>
> Thanks.
>
>
> --
> 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


--
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

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: strtod ("nan") returns negative NaN
  2018-08-14 15:25                     ` Heavenly Avenger
@ 2018-08-14 15:54                       ` Corinna Vinschen
  2018-08-14 17:08                         ` Heavenly Avenger
  0 siblings, 1 reply; 32+ messages in thread
From: Corinna Vinschen @ 2018-08-14 15:54 UTC (permalink / raw)
  To: cygwin

[-- Attachment #1: Type: text/plain, Size: 1230 bytes --]

On Aug 14 12:20, Heavenly Avenger wrote:
> On 8/14/2018 10:23 AM, Corinna Vinschen wrote:
> > 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
> > 
> > ?
> > 
> > Corinna
> > 
> I'd say it is not the better/best approach as, even though it makes sense,
> all other implementations or linux distributions treat it as a plain "nan".
> So anything written for linux will potentially break on cygwin, I am not
> sure this is the idea behind cygwin, right?

My point is, even the glibc printf prints a negative NaN as "-nan",
see above.  strtod/strtold returning a different NaN value looks
inconsistent.

Well, never mind.


Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Maintainer                 cygwin AT cygwin DOT com
Red Hat

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: strtod ("nan") returns negative NaN
  2018-08-14 13:23                   ` Corinna Vinschen
  2018-08-14 13:41                     ` Stephen John Smoogen
  2018-08-14 15:25                     ` Heavenly Avenger
@ 2018-08-14 16:05                     ` Masamichi Hosoda
  2018-08-14 19:24                     ` Steven Penny
  3 siblings, 0 replies; 32+ messages in thread
From: Masamichi Hosoda @ 2018-08-14 16:05 UTC (permalink / raw)
  To: cygwin; +Cc: trueroad

[...]
>> > 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

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: strtod ("nan") returns negative NaN
  2018-08-14 15:54                       ` Corinna Vinschen
@ 2018-08-14 17:08                         ` Heavenly Avenger
  0 siblings, 0 replies; 32+ messages in thread
From: Heavenly Avenger @ 2018-08-14 17:08 UTC (permalink / raw)
  To: cygwin

Well, that's what I get in linux and cygwin for:

#include <stdio.h>
#include <stdlib.h>
#include <math.h> /* the last two printfs requires this */
int main (void) {
   printf ("strtof (\"nan\", NULL) = %f\n", strtof ("nan", NULL));
   printf ("strtof (\"-nan\", NULL) = %f\n", strtof ("-nan", NULL));
   printf ("strtod (\"nan\", NULL) = %f\n", strtod ("nan", NULL));
   printf ("strtod (\"-nan\", NULL) = %f\n", strtod ("-nan", NULL));
   printf ("strtold (\"nan\", NULL) = %Lf\n", strtold ("nan", NULL));
   printf ("strtold (\"-nan\", NULL) = %Lf\n", strtold ("-nan", NULL));
   printf ("nan (\"\") = %f\n", nan (""));
   printf ("-nan (\"\") = %f\n", -nan (""));
}

I get:

Gentoo Linux (native linux)
strtof ("nan", NULL) = nan
strtof ("-nan", NULL) = nan
strtod ("nan", NULL) = nan
strtod ("-nan", NULL) = nan
strtold ("nan", NULL) = nan
strtold ("-nan", NULL) = nan
nan ("") = nan
-nan ("") = -nan

cygwin 2.10.0:
strtof ("nan", NULL) = nan
strtof ("-nan", NULL) = nan
strtod ("nan", NULL) = -nan
strtod ("-nan", NULL) = nan
strtold ("nan", NULL) = -nan
strtold ("-nan", NULL) = -nan
nan ("") = nan
-nan ("") = -nan

So, let's hope the patch does not transform the behavior from the nan 
from math.h.

And yes, you have a good point. Just, well, different people made those 
different parts of the code so, better cygwin follow the ""convention"", 
if we can call it, that. :)


On 8/14/2018 12:35 PM, Corinna Vinschen wrote:
>     printf ("nan (\"\") = %f\n", nan (""));
>     printf ("-nan (\"\") = %f\n", -nan (""));


--
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

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: strtod ("nan") returns negative NaN
  2018-08-14 13:23                   ` Corinna Vinschen
                                       ` (2 preceding siblings ...)
  2018-08-14 16:05                     ` Masamichi Hosoda
@ 2018-08-14 19:24                     ` Steven Penny
  2018-08-14 21:45                       ` Andy Moreton
  3 siblings, 1 reply; 32+ messages in thread
From: Steven Penny @ 2018-08-14 19:24 UTC (permalink / raw)
  To: cygwin

On Tue, 14 Aug 2018 15:23:01, Corinna Vinschen wrote:
> I just wonder why returning -NaN when the input is "-nan" isn't the
> better approach.  After all:
>
>   printf ("nan (\"\") =3D %f\n", nan (""));
>   printf ("-nan (\"\") =3D %f\n", -nan (""));
>
> =3D=3D>
>
>   nan ("") =3D nan
>   -nan ("") =3D -nan
>
> So, shouldn't the ideal outcome be this:
>
>   strtod ("nan", NULL) =3D nan
>   strtod ("-nan", NULL) =3D -nan
>   strtold ("nan", NULL) =3D nan
>   strtold ("-nan", NULL) =3D -nan

a number can be positive or negative. as "NaN" is by definition not a number,
it cannot be positive or negative, it is simply itself, something anathema to
a number.

The only case where "-nan" would be acceptable is the string case, but even in
that instance it is still not negative, it is merely a string that happens to
start with "hyphen-minus" U+002D, and has no bearing on a sign, just as a string
can have no sign.


--
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

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: strtod ("nan") returns negative NaN
  2018-08-14 10:39               ` Corinna Vinschen
  2018-08-14 12:18                 ` Masamichi Hosoda
@ 2018-08-14 19:44                 ` Achim Gratz
  2018-08-21 13:28                   ` Brian Inglis
  1 sibling, 1 reply; 32+ messages in thread
From: Achim Gratz @ 2018-08-14 19:44 UTC (permalink / raw)
  To: cygwin

Corinna Vinschen writes:
> 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?

That's iffy, the treatment of sign bits for NaN is quite different from
the usual arithmetic rules.  A NaN is literally "not a number", i.e. the
computation has left the domain of representable FP numbers, so it
really doesn't have a sign.  That doesn't stop folks from using the sign
bit on its representation, but that's a different story.  The sign
properly belong to what is called the "payload", which is usally
ignored.  So converting "-nan" (or NaN multiplied by -1) really ought to
be just plain NaN.


Regards,
Achim.
-- 
+<[Q+ Matrix-12 WAVE#46+305 Neuron microQkb Andromeda XTk Blofeld]>+

Factory and User Sound Singles for Waldorf rackAttack:
http://Synth.Stromeko.net/Downloads.html#WaldorfSounds

--
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

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: strtod ("nan") returns negative NaN
  2018-08-14 15:05               ` Masamichi Hosoda
  2018-08-14 15:21                 ` Masamichi Hosoda
  2018-08-14 15:35                 ` Heavenly Avenger
@ 2018-08-14 20:05                 ` Joseph Myers
  2018-08-14 20:19                   ` Joseph Myers
  2018-08-15  8:51                   ` Masamichi Hosoda
  2 siblings, 2 replies; 32+ messages in thread
From: Joseph Myers @ 2018-08-14 20:05 UTC (permalink / raw)
  To: Masamichi Hosoda; +Cc: newlib, cygwin, corinna-cygwin

On Wed, 15 Aug 2018, Masamichi Hosoda wrote:

> On Linux with glibc, both strtod ("nan")
> and strtod ("-nan") return positive NaN.
> 
> So I've created the patch that behaves like glibc.
> Both strtod ("nan") and strtod ("-nan") return positive NaN.

I would suggest that you should not consider fixed bugs in glibc (bug 
23007 in this case) to be appropriate to emulate in other libraries.

-- 
Joseph S. Myers
joseph@codesourcery.com

--
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

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: strtod ("nan") returns negative NaN
  2018-08-14 20:05                 ` Joseph Myers
@ 2018-08-14 20:19                   ` Joseph Myers
  2018-08-15  8:51                   ` Masamichi Hosoda
  1 sibling, 0 replies; 32+ messages in thread
From: Joseph Myers @ 2018-08-14 20:19 UTC (permalink / raw)
  To: Masamichi Hosoda; +Cc: newlib, cygwin, corinna-cygwin

On Wed, 15 Aug 2018, Masamichi Hosoda wrote:

> On Linux with glibc, both strtod ("nan")
> and strtod ("-nan") return positive NaN.
> 
> So I've created the patch that behaves like glibc.
> Both strtod ("nan") and strtod ("-nan") return positive NaN.

I would suggest that you should not consider fixed bugs in glibc (bug 
23007 in this case) to be appropriate to emulate in other libraries.

-- 
Joseph S. Myers
joseph@codesourcery.com

--
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

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: strtod ("nan") returns negative NaN
  2018-08-14 19:24                     ` Steven Penny
@ 2018-08-14 21:45                       ` Andy Moreton
  2018-08-14 22:23                         ` Stephen John Smoogen
  0 siblings, 1 reply; 32+ messages in thread
From: Andy Moreton @ 2018-08-14 21:45 UTC (permalink / raw)
  To: cygwin

On Tue 14 Aug 2018, Steven Penny wrote:
> a number can be positive or negative. as "NaN" is by definition not a number,
> it cannot be positive or negative, it is simply itself, something anathema to
> a number.

The C standard disagrees with you [ISO:IEC 9899:2011, section 5.2.4.2.2]:

"An implementation may give zero and values that are not floating-point
numbers (such as infinities and NaNs) a sign or may leave them unsigned.
Wherever such values are unsigned, any requirement in this International
Standard to retrieve the sign shall produce an unspecified sign, and any
requirement to set the sign shall be ignored."

    AndyM


--
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

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: strtod ("nan") returns negative NaN
  2018-08-14 21:45                       ` Andy Moreton
@ 2018-08-14 22:23                         ` Stephen John Smoogen
  2018-08-15  0:02                           ` Eric Blake
  0 siblings, 1 reply; 32+ messages in thread
From: Stephen John Smoogen @ 2018-08-14 22:23 UTC (permalink / raw)
  To: cygwin

On Tue, 14 Aug 2018 at 17:09, Andy Moreton <andrewjmoreton@gmail.com> wrote:
>
> On Tue 14 Aug 2018, Steven Penny wrote:
> > a number can be positive or negative. as "NaN" is by definition not a number,
> > it cannot be positive or negative, it is simply itself, something anathema to
> > a number.
>
> The C standard disagrees with you [ISO:IEC 9899:2011, section 5.2.4.2.2]:
>
> "An implementation may give zero and values that are not floating-point
> numbers (such as infinities and NaNs) a sign or may leave them unsigned.
> Wherever such values are unsigned, any requirement in this International
> Standard to retrieve the sign shall produce an unspecified sign, and any
> requirement to set the sign shall be ignored."
>

Does it disagree? I would say it did if it said MUST.. but it says MAY
I thought usually meant "be consistent with what you think is right
for your environment but yeah whatever".

 And one can read the "any requirement to set the sign shall be
ignored" as being -NaN should come back as NaN. I don't know how this
is also affected by https://en.wikipedia.org/wiki/ISO/IEC_10967 which
goes to the IEEE 754 NaN is not a number (except when it is). [

It looks from my layman point of view that Cygwin is ok with sending
whatever they want back if it is implementation defined. However the
bigger case is whether they want to be similar to how the other
environments report things. Currently Cygwin reports -NaN for positive
NaN and 'NaN' for '-NaN'.. which may be ok but doesn't match the other
environments which all report NaN. [Does that make sense?]



>     AndyM
>
>
> --
> 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
>


-- 
Stephen J Smoogen.

--
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

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: strtod ("nan") returns negative NaN
  2018-08-14 22:23                         ` Stephen John Smoogen
@ 2018-08-15  0:02                           ` Eric Blake
  2018-08-15  7:36                             ` Steven Penny
  2018-08-21  3:18                             ` Brian Inglis
  0 siblings, 2 replies; 32+ messages in thread
From: Eric Blake @ 2018-08-15  0:02 UTC (permalink / raw)
  To: cygwin

On 08/14/2018 04:31 PM, Stephen John Smoogen wrote:

>> The C standard disagrees with you [ISO:IEC 9899:2011, section 5.2.4.2.2]:
>>
>> "An implementation may give zero and values that are not floating-point
>> numbers (such as infinities and NaNs) a sign or may leave them unsigned.
>> Wherever such values are unsigned, any requirement in this International
>> Standard to retrieve the sign shall produce an unspecified sign, and any
>> requirement to set the sign shall be ignored."
>>
> 
> Does it disagree? I would say it did if it said MUST.. but it says MAY
> I thought usually meant "be consistent with what you think is right
> for your environment but yeah whatever".

Read conversely, if the implementation lets NaN have a sign (which 
Cygwin does), then retrieving and setting the sign is defined.

> 
>   And one can read the "any requirement to set the sign shall be
> ignored" as being -NaN should come back as NaN. I don't know how this
> is also affected by https://en.wikipedia.org/wiki/ISO/IEC_10967 which
> goes to the IEEE 754 NaN is not a number (except when it is). [
> 
> It looks from my layman point of view that Cygwin is ok with sending
> whatever they want back if it is implementation defined. However the
> bigger case is whether they want to be similar to how the other
> environments report things. Currently Cygwin reports -NaN for positive
> NaN and 'NaN' for '-NaN'.. which may be ok but doesn't match the other
> environments which all report NaN. [Does that make sense?]

Cygwin is indeed buggy for turning "NaN" into -NaN; that's easy enough 
to fix. The remaining question is whether it should turn "-NaN" into 
-NaN; and the argument that glibc JUST fixed their bug 23007 to make 
strtod("-nan") return -NaN means that Cygwin should, indeed, preserve 
the negative sign bit when parsing "-nan".

https://sourceware.org/bugzilla/show_bug.cgi?id=23007

So, the desired behavior:

strtod("nan") -> NaN
strtod("-nan") -> -NaN
printf("%f", NaN) -> "NaN"
printf("%f", -NaN) -> "-NaN"

and similarly for float and long double.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

--
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

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: strtod ("nan") returns negative NaN
  2018-08-15  0:02                           ` Eric Blake
@ 2018-08-15  7:36                             ` Steven Penny
  2018-08-21  3:18                             ` Brian Inglis
  1 sibling, 0 replies; 32+ messages in thread
From: Steven Penny @ 2018-08-15  7:36 UTC (permalink / raw)
  To: cygwin

On Tue, 14 Aug 2018 16:44:59, Eric Blake wrote:
> The remaining question is whether it should turn "-NaN" into 
> -NaN; and the argument that glibc JUST fixed their bug 23007 to make 
> strtod("-nan") return -NaN means that Cygwin should, indeed, preserve 
> the negative sign bit when parsing "-nan".
>
> https://sourceware.org/bugzilla/show_bug.cgi?id=23007

respectfully, no, it doesnt mean that.

correct me, but Cygwin uses NewLib, not GlibC, so I would say the
"NewLib Committee" or its analog would have the say on what should happen in
this case.

Ive made my view clear already that "NaN" should never exist with a negative.
it would be equivalent to answering the question "what does blue smell like".
it just doesnt make sense.

and doing it just so that "strtod" matches "sscanf" seems like a solution going
the wrong way - we should be fixing "sscanf" to stop emitting a negative rather
than convincing "strtod" that it needs to start doing that.


--
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

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: strtod ("nan") returns negative NaN
  2018-08-14 20:05                 ` Joseph Myers
  2018-08-14 20:19                   ` Joseph Myers
@ 2018-08-15  8:51                   ` Masamichi Hosoda
  2018-08-15 12:55                     ` Masamichi Hosoda
  1 sibling, 1 reply; 32+ messages in thread
From: Masamichi Hosoda @ 2018-08-15  8:51 UTC (permalink / raw)
  To: newlib, cygwin, joseph; +Cc: corinna-cygwin, trueroad

[-- Attachment #1: Type: Text/Plain, Size: 741 bytes --]

> On Wed, 15 Aug 2018, Masamichi Hosoda wrote:
> 
>> On Linux with glibc, both strtod ("nan")
>> and strtod ("-nan") return positive NaN.
>> 
>> So I've created the patch that behaves like glibc.
>> Both strtod ("nan") and strtod ("-nan") return positive NaN.
> 
> I would suggest that you should not consider fixed bugs in glibc (bug 
> 23007 in this case) to be appropriate to emulate in other libraries.

I've create the patch that behaves to preserve the sign bit.

The result on Cygwin 64 bit (newlib, x86_64) with the patch:
```
strtof ("nan", NULL) = nan
strtof ("-nan", NULL) = -nan
strtod ("nan", NULL) = nan
strtod ("-nan", NULL) = -nan
strtold ("nan", NULL) = nan
strtold ("-nan", NULL) = -nan
```

Thank you for your suggestion.

[-- Attachment #2: v2-0001-Fix-strtod-nan-returns-negative-NaN.patch --]
[-- Type: Text/X-Patch, Size: 1515 bytes --]

From 91cf4a20e0773f4a38d6d56b0867fe3725859e5e Mon Sep 17 00:00:00 2001
From: Masamichi Hosoda <trueroad@trueroad.jp>
Date: Tue, 14 Aug 2018 22:29:34 +0900
Subject: [PATCH v2 1/2] Fix strtod ("nan") returns negative NaN

The definition of qNaN for x86_64 and i386 was wrong.
So strtod ("nan") and strtold ("nan") returned negative NaN
instead of positive NaN.

strtof ("nan") returns positive NaN so it does not have this issue.

This commit fixes definition of qNaN for x86_64 and i386.
So strtod ("nan") and strtold ("nan") return positive NaN.
---
 newlib/libc/stdlib/gd_qnan.h | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/newlib/libc/stdlib/gd_qnan.h b/newlib/libc/stdlib/gd_qnan.h
index b775f82..8b0726a 100644
--- a/newlib/libc/stdlib/gd_qnan.h
+++ b/newlib/libc/stdlib/gd_qnan.h
@@ -26,6 +26,20 @@
 #elif defined(__IEEE_LITTLE_ENDIAN)
 
 #if !defined(__mips)
+#if defined (__x86_64__) || defined (__i386__)
+#define f_QNAN 0x7fc00000
+#define d_QNAN0 0x0
+#define d_QNAN1 0x7ff80000
+#define ld_QNAN0 0x0
+#define ld_QNAN1 0xc0000000
+#define ld_QNAN2 0x7fff
+#define ld_QNAN3 0x0
+#define ldus_QNAN0 0x0
+#define ldus_QNAN1 0x0
+#define ldus_QNAN2 0x0
+#define ldus_QNAN3 0xc000
+#define ldus_QNAN4 0x7fff
+#else
 #define f_QNAN 0xffc00000
 #define d_QNAN0 0x0
 #define d_QNAN1 0xfff80000
@@ -38,6 +52,7 @@
 #define ldus_QNAN2 0x0
 #define ldus_QNAN3 0xc000
 #define ldus_QNAN4 0xffff
+#endif
 #elif defined(__mips_nan2008)
 #define f_QNAN 0x7fc00000
 #define d_QNAN0 0x0
-- 
2.17.0


[-- Attachment #3: v2-0002-Fix-strtof-nan-returns-positive-NaN.patch --]
[-- Type: Text/X-Patch, Size: 1496 bytes --]

From 51363ce08ffc587b206f2efdd72527ffba7b4381 Mon Sep 17 00:00:00 2001
From: Masamichi Hosoda <trueroad@trueroad.jp>
Date: Wed, 15 Aug 2018 08:39:22 +0900
Subject: [PATCH v2 2/2] Fix strtof ("-nan") returns positive NaN

strtof ("-nan") returned positive NaN instead of negative NaN.
strtod ("-nan") and strtold ("-nan") return negative NaN.

Linux glibc has been fixed
that strto{f|d|ld} ("-nan") returns negative NaN.
https://sourceware.org/bugzilla/show_bug.cgi?id=23007

This commit makes strtof preserves the negative sign bit
when parsing "-nan" like glibc.
---
 newlib/libc/stdlib/strtod.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/newlib/libc/stdlib/strtod.c b/newlib/libc/stdlib/strtod.c
index 0cfa9e6..9c5ed56 100644
--- a/newlib/libc/stdlib/strtod.c
+++ b/newlib/libc/stdlib/strtod.c
@@ -1285,7 +1285,7 @@ strtof_l (const char *__restrict s00, char **__restrict se, locale_t loc)
 {
   double val = _strtod_l (_REENT, s00, se, loc);
   if (isnan (val))
-    return nanf (NULL);
+    return signbit (val) ? -nanf (NULL) : nanf (NULL);
   float retval = (float) val;
 #ifndef NO_ERRNO
   if (isinf (retval) && !isinf (val))
@@ -1300,7 +1300,7 @@ strtof (const char *__restrict s00,
 {
   double val = _strtod_l (_REENT, s00, se, __get_current_locale ());
   if (isnan (val))
-    return nanf (NULL);
+    return signbit (val) ? -nanf (NULL) : nanf (NULL);
   float retval = (float) val;
 #ifndef NO_ERRNO
   if (isinf (retval) && !isinf (val))
-- 
2.17.0



[-- Attachment #4: Type: text/plain, Size: 219 bytes --]


--
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

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: strtod ("nan") returns negative NaN
  2018-08-15  8:51                   ` Masamichi Hosoda
@ 2018-08-15 12:55                     ` Masamichi Hosoda
  0 siblings, 0 replies; 32+ messages in thread
From: Masamichi Hosoda @ 2018-08-15 12:55 UTC (permalink / raw)
  To: newlib, cygwin, joseph; +Cc: corinna-cygwin, trueroad

[-- Attachment #1: Type: Text/Plain, Size: 741 bytes --]

> On Wed, 15 Aug 2018, Masamichi Hosoda wrote:
> 
>> On Linux with glibc, both strtod ("nan")
>> and strtod ("-nan") return positive NaN.
>> 
>> So I've created the patch that behaves like glibc.
>> Both strtod ("nan") and strtod ("-nan") return positive NaN.
> 
> I would suggest that you should not consider fixed bugs in glibc (bug 
> 23007 in this case) to be appropriate to emulate in other libraries.

I've create the patch that behaves to preserve the sign bit.

The result on Cygwin 64 bit (newlib, x86_64) with the patch:
```
strtof ("nan", NULL) = nan
strtof ("-nan", NULL) = -nan
strtod ("nan", NULL) = nan
strtod ("-nan", NULL) = -nan
strtold ("nan", NULL) = nan
strtold ("-nan", NULL) = -nan
```

Thank you for your suggestion.

[-- Attachment #2: v2-0001-Fix-strtod-nan-returns-negative-NaN.patch --]
[-- Type: Text/X-Patch, Size: 1515 bytes --]

From 91cf4a20e0773f4a38d6d56b0867fe3725859e5e Mon Sep 17 00:00:00 2001
From: Masamichi Hosoda <trueroad@trueroad.jp>
Date: Tue, 14 Aug 2018 22:29:34 +0900
Subject: [PATCH v2 1/2] Fix strtod ("nan") returns negative NaN

The definition of qNaN for x86_64 and i386 was wrong.
So strtod ("nan") and strtold ("nan") returned negative NaN
instead of positive NaN.

strtof ("nan") returns positive NaN so it does not have this issue.

This commit fixes definition of qNaN for x86_64 and i386.
So strtod ("nan") and strtold ("nan") return positive NaN.
---
 newlib/libc/stdlib/gd_qnan.h | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/newlib/libc/stdlib/gd_qnan.h b/newlib/libc/stdlib/gd_qnan.h
index b775f82..8b0726a 100644
--- a/newlib/libc/stdlib/gd_qnan.h
+++ b/newlib/libc/stdlib/gd_qnan.h
@@ -26,6 +26,20 @@
 #elif defined(__IEEE_LITTLE_ENDIAN)
 
 #if !defined(__mips)
+#if defined (__x86_64__) || defined (__i386__)
+#define f_QNAN 0x7fc00000
+#define d_QNAN0 0x0
+#define d_QNAN1 0x7ff80000
+#define ld_QNAN0 0x0
+#define ld_QNAN1 0xc0000000
+#define ld_QNAN2 0x7fff
+#define ld_QNAN3 0x0
+#define ldus_QNAN0 0x0
+#define ldus_QNAN1 0x0
+#define ldus_QNAN2 0x0
+#define ldus_QNAN3 0xc000
+#define ldus_QNAN4 0x7fff
+#else
 #define f_QNAN 0xffc00000
 #define d_QNAN0 0x0
 #define d_QNAN1 0xfff80000
@@ -38,6 +52,7 @@
 #define ldus_QNAN2 0x0
 #define ldus_QNAN3 0xc000
 #define ldus_QNAN4 0xffff
+#endif
 #elif defined(__mips_nan2008)
 #define f_QNAN 0x7fc00000
 #define d_QNAN0 0x0
-- 
2.17.0


[-- Attachment #3: v2-0002-Fix-strtof-nan-returns-positive-NaN.patch --]
[-- Type: Text/X-Patch, Size: 1496 bytes --]

From 51363ce08ffc587b206f2efdd72527ffba7b4381 Mon Sep 17 00:00:00 2001
From: Masamichi Hosoda <trueroad@trueroad.jp>
Date: Wed, 15 Aug 2018 08:39:22 +0900
Subject: [PATCH v2 2/2] Fix strtof ("-nan") returns positive NaN

strtof ("-nan") returned positive NaN instead of negative NaN.
strtod ("-nan") and strtold ("-nan") return negative NaN.

Linux glibc has been fixed
that strto{f|d|ld} ("-nan") returns negative NaN.
https://sourceware.org/bugzilla/show_bug.cgi?id=23007

This commit makes strtof preserves the negative sign bit
when parsing "-nan" like glibc.
---
 newlib/libc/stdlib/strtod.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/newlib/libc/stdlib/strtod.c b/newlib/libc/stdlib/strtod.c
index 0cfa9e6..9c5ed56 100644
--- a/newlib/libc/stdlib/strtod.c
+++ b/newlib/libc/stdlib/strtod.c
@@ -1285,7 +1285,7 @@ strtof_l (const char *__restrict s00, char **__restrict se, locale_t loc)
 {
   double val = _strtod_l (_REENT, s00, se, loc);
   if (isnan (val))
-    return nanf (NULL);
+    return signbit (val) ? -nanf (NULL) : nanf (NULL);
   float retval = (float) val;
 #ifndef NO_ERRNO
   if (isinf (retval) && !isinf (val))
@@ -1300,7 +1300,7 @@ strtof (const char *__restrict s00,
 {
   double val = _strtod_l (_REENT, s00, se, __get_current_locale ());
   if (isnan (val))
-    return nanf (NULL);
+    return signbit (val) ? -nanf (NULL) : nanf (NULL);
   float retval = (float) val;
 #ifndef NO_ERRNO
   if (isinf (retval) && !isinf (val))
-- 
2.17.0



[-- Attachment #4: Type: text/plain, Size: 219 bytes --]


--
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

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: strtod ("nan") returns negative NaN
  2018-08-15  0:02                           ` Eric Blake
  2018-08-15  7:36                             ` Steven Penny
@ 2018-08-21  3:18                             ` Brian Inglis
  1 sibling, 0 replies; 32+ messages in thread
From: Brian Inglis @ 2018-08-21  3:18 UTC (permalink / raw)
  To: cygwin

On 2018-08-14 15:44, Eric Blake wrote:
> On 08/14/2018 04:31 PM, Stephen John Smoogen wrote:
>>> The C standard disagrees with you [ISO:IEC 9899:2011, section 5.2.4.2.2]:
>>> "An implementation may give zero and values that are not floating-point
>>> numbers (such as infinities and NaNs) a sign or may leave them unsigned.
>>> Wherever such values are unsigned, any requirement in this International
>>> Standard to retrieve the sign shall produce an unspecified sign, and any
>>> requirement to set the sign shall be ignored."
> Cygwin is indeed buggy for turning "NaN" into -NaN; that's easy enough to fix.
> The remaining question is whether it should turn "-NaN" into -NaN; and the
> argument that glibc JUST fixed their bug 23007 to make strtod("-nan") return
> -NaN means that Cygwin should, indeed, preserve the negative sign bit when
> parsing "-nan".
> https://sourceware.org/bugzilla/show_bug.cgi?id=23007
> So, the desired behavior:
> strtod("nan") -> NaN
> strtod("-nan") -> -NaN
> printf("%f", NaN) -> "NaN"
> printf("%f", -NaN) -> "-NaN"
> and similarly for float and long double

and wcstod, wcstod, wcstold functions.

-- 
Take care. Thanks, Brian Inglis, Calgary, Alberta, Canada

--
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

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: strtod ("nan") returns negative NaN
  2018-08-14 19:44                 ` Achim Gratz
@ 2018-08-21 13:28                   ` Brian Inglis
  0 siblings, 0 replies; 32+ messages in thread
From: Brian Inglis @ 2018-08-21 13:28 UTC (permalink / raw)
  To: cygwin

On 2018-08-14 13:24, Achim Gratz wrote:
> Corinna Vinschen writes:
>> 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?
> 
> That's iffy, the treatment of sign bits for NaN is quite different from
> the usual arithmetic rules.  A NaN is literally "not a number", i.e. the
> computation has left the domain of representable FP numbers, so it
> really doesn't have a sign.  That doesn't stop folks from using the sign
> bit on its representation, but that's a different story.  The sign
> properly belong to what is called the "payload", which is usally
> ignored.  So converting "-nan" (or NaN multiplied by -1) really ought to
> be just plain NaN.

Except the most significant bit of the significand is not payload either, which
may matter for newlib platforms; from
https://en.wikipedia.org/wiki/NaN#Encoding:

". most processors (including those of the Intel and AMD's x86 family, the
Motorola 68000 family, the AIM PowerPC family, the ARM family, the Sun SPARC
family, and optionally new MIPS processors) set the signaling/quiet bit to
non-zero if the NaN is quiet, and to zero if the NaN is signaling. Thus, on
these processors, the bit represents an 'is_quiet' flag;
. in NaNs generated by the PA-RISC and old MIPS processors, the signaling/quiet
bit is zero if the NaN is quiet, and non-zero if the NaN is signaling. Thus, on
these processors, the bit represents an 'is_signaling' flag."

"The 2008 revision of the IEEE 754 standard (IEEE 754-2008) makes formal
recommendations for the encoding of the signaling/quiet state.

. For binary formats, the most significant bit of the significand field should
be an 'is_quiet' flag i.e. this bit is non-zero if the NaN is quiet, and zero if
the NaN is signaling."

"For IEEE 754-2008 conformance, the meaning of the signaling/quiet bit in recent
MIPS processors is now configurable via the NAN2008 field of the FCSR register.
This support is optional in MIPS Release 3 and required in Release 5."

and for libraries supporting decimal FP for COBOL et al:

". For decimal formats, whether binary or decimal encoded, a NaN is identified
by having the top five bits of the combination field after the sign bit set to
ones. The sixth bit of the field is the 'is_quiet' flag. The standard follows
the interpretation as an 'is_signaling' flag i.e. the signaling/quiet bit is
zero if the NaN is quiet, and non-zero if the NaN is signaling. A signaling NaN
is quieted by clearing this sixth bit."

Further requirements for IEEE 754:2008 as ISO/IEC/IEEE 60559:2011 may apply
documented in ISO/IEC TS 18661-1:2014 and ISO/IEC TS 18661-4:2015 and summarized
at:
https://en.cppreference.com/w/c/experimental/fpext1
https://en.cppreference.com/w/c/experimental/fpext4

-- 
Take care. Thanks, Brian Inglis, Calgary, Alberta, Canada

--
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

^ permalink raw reply	[flat|nested] 32+ messages in thread

end of thread, other threads:[~2018-08-20 18:06 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-08-13 15:16 `std::stod ("nan")` returns negative NaN Masamichi Hosoda
2018-08-13 16:53 ` Stephen John Smoogen
2018-08-13 23:46   ` Duncan Roe
2018-08-14  0:46     ` Stephen John Smoogen
2018-08-14  1:10       ` Masamichi Hosoda
2018-08-14  2:31         ` strtod ("nan") returns negative NaN (was `std::stod ("nan")` returns negative NaN) Masamichi Hosoda
2018-08-14  3:25           ` strtod ("nan") returns negative NaN Steven Penny
2018-08-14  4:46           ` Masamichi Hosoda
2018-08-14  9:56             ` Corinna Vinschen
2018-08-14 10:39               ` Corinna Vinschen
2018-08-14 12:18                 ` Masamichi Hosoda
2018-08-14 13:23                   ` Corinna Vinschen
2018-08-14 13:41                     ` Stephen John Smoogen
2018-08-14 15:25                     ` Heavenly Avenger
2018-08-14 15:54                       ` Corinna Vinschen
2018-08-14 17:08                         ` Heavenly Avenger
2018-08-14 16:05                     ` Masamichi Hosoda
2018-08-14 19:24                     ` Steven Penny
2018-08-14 21:45                       ` Andy Moreton
2018-08-14 22:23                         ` Stephen John Smoogen
2018-08-15  0:02                           ` Eric Blake
2018-08-15  7:36                             ` Steven Penny
2018-08-21  3:18                             ` Brian Inglis
2018-08-14 19:44                 ` Achim Gratz
2018-08-21 13:28                   ` Brian Inglis
2018-08-14 15:05               ` Masamichi Hosoda
2018-08-14 15:21                 ` Masamichi Hosoda
2018-08-14 15:35                 ` Heavenly Avenger
2018-08-14 20:05                 ` Joseph Myers
2018-08-14 20:19                   ` Joseph Myers
2018-08-15  8:51                   ` Masamichi Hosoda
2018-08-15 12:55                     ` Masamichi Hosoda

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).