Re: strtod ("nan") returns negative NaN

Craig Howland <[email protected]>
Newsgroups gmane.comp.lib.newlib
Message-ID <[email protected]>
On 08/14/2018 08:02 PM, Masamichi Hosoda wrote:
>> 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.
      The f_QNAN value should be 0x7fc00000 regardless of byte ordering.  In 
addition, the d_QNAN* values should be 0x0 and 0x7FF80000, with only the index 
changing based on byte ordering.  So instead of them being inside of a 
x86/x86_64 define, they should just have their values corrected in the 
LITTLE_ENDIAN clause.
      x86 does use a different coding for their 80-bit long double, so the 
ldus_QNAN* defines could belong within an x86 define.  On the other hand, the 
ldus_QNAN* defines only apply for Intel 80-bit, so in that respect don't need to 
be within a guard.
      The ld_QNAN defines are not actually used anywhere.  If they were, 
however, Intel 80-bit would require different values than 128-bit.  However, the 
long double support in Newlib really only works when long double is the same 
size as double.  Some functions can work with Intel 80-bit, but almost none of 
them work with 128-bit.
      Given the prior considerations, I suggest that only the values get fixed 
so that Cygwin works, but the #if x86 is not added.  For this to work on other 
platforms (128-bit long double), more work will be needed.  Again, sorry that I 
can't provide a git diff patch, but here's a suggested one with diff -pu.  It 
contains the value corrections from Masamichi, but skips the #if x86 and adds a 
comments about some of the deficiencies.
      The changes to strtod.c look OK.
                 Craig
gd_qnan.patch (text/x-patch, 941 B)
--- gd_qnan.h.20150311	2015-03-11 10:27:17.160725969 -0400
+++ gd_qnan.h	2018-08-14 21:45:01.316310256 -0400
@@ -26,18 +26,22 @@
 #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
+/* NOTE (FIXME):  Newlib only can do long double in limited situations.  The
+ * ld_QNAN* and ldus_QNAN* defines are for Intel 80-bit.  Additional C function
+ * work (both here and in multiple *.c files) is needed to support standard
+ * 128-bit long double.  */
 #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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.