On Mon, 16 Apr 2018 18:06:32 -0400
George Koehler <[email protected]> wrote:

>       In some platforms (like amd64, but not macppc), strtod(3)
>       flips the sign of not-a-number (nan).  It changes "nan" into
>       -nan and "-nan" into nan.

I had sent a patch for strtod() on amd64, but I forgot to fix
strtof() and strtold().  I now send a patch for all 3 functions on
amd64.  This patch also tries to fix alpha, arm, and i386, but I only
tested amd64.  I know that powerpc doesn't have the bug, and I guess
that other arches might not have the bug.

To check for the bug, compile this program "try.c":

#include <stdlib.h>
#include <stdio.h>
int main(int argc, const char **argv) {
        if (argc != 2) return 1;
        printf("%g\n", strtof(argv[1], NULL));
        printf("%g\n", strtod(argv[1], NULL));
        printf("%Lg\n", strtold(argv[1], NULL));
        return 0;
}

If the bug is fixed, then `./try nan` outputs `nan` 3 times, and
`./try -nan` outputs `-nan` 3 times.

To fetch the source code of OpenBSD, see
https://www.openbsd.org/faq/faq5.html#Bld

To apply the patch:
$ cd /usr/src/lib/libc
$ patch </tmp/this-email

Then become root and rebuild libc:
# make obj
# make
# make install

Index: arch/alpha/gdtoa/gd_qnan.h
===================================================================
RCS file: /cvs/src/lib/libc/arch/alpha/gdtoa/gd_qnan.h,v
retrieving revision 1.1
diff -u -p -u -r1.1 gd_qnan.h
--- arch/alpha/gdtoa/gd_qnan.h  7 Sep 2008 20:36:07 -0000       1.1
+++ arch/alpha/gdtoa/gd_qnan.h  23 Apr 2018 23:41:20 -0000
@@ -1,12 +1,12 @@
-#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 0xfff80000
+#define ld_QNAN1 0x7ff80000
 #define ld_QNAN2 0x0
 #define ld_QNAN3 0x0
 #define ldus_QNAN0 0x0
 #define ldus_QNAN1 0x0
 #define ldus_QNAN2 0x0
-#define ldus_QNAN3 0xfff8
+#define ldus_QNAN3 0x7ff8
 #define ldus_QNAN4 0x0
Index: arch/amd64/gdtoa/gd_qnan.h
===================================================================
RCS file: /cvs/src/lib/libc/arch/amd64/gdtoa/gd_qnan.h,v
retrieving revision 1.1
diff -u -p -u -r1.1 gd_qnan.h
--- arch/amd64/gdtoa/gd_qnan.h  7 Sep 2008 20:36:07 -0000       1.1
+++ arch/amd64/gdtoa/gd_qnan.h  23 Apr 2018 23:41:20 -0000
@@ -1,12 +1,12 @@
-#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
Index: arch/arm/gdtoa/gd_qnan.h
===================================================================
RCS file: /cvs/src/lib/libc/arch/arm/gdtoa/gd_qnan.h,v
retrieving revision 1.1
diff -u -p -u -r1.1 gd_qnan.h
--- arch/arm/gdtoa/gd_qnan.h    7 Sep 2008 20:36:07 -0000       1.1
+++ arch/arm/gdtoa/gd_qnan.h    23 Apr 2018 23:41:20 -0000
@@ -1,12 +1,12 @@
-#define f_QNAN 0xffffffff
+#define f_QNAN 0x7fffffff
 #define d_QNAN0 0xffffffff
-#define d_QNAN1 0xffffffff
+#define d_QNAN1 0x7fffffff
 #define ld_QNAN0 0xffffffff
-#define ld_QNAN1 0xffffffff
+#define ld_QNAN1 0x7fffffff
 #define ld_QNAN2 0x0
 #define ld_QNAN3 0x0
 #define ldus_QNAN0 0xffff
 #define ldus_QNAN1 0xffff
 #define ldus_QNAN2 0xffff
-#define ldus_QNAN3 0xffff
+#define ldus_QNAN3 0x7fff
 #define ldus_QNAN4 0x0
Index: arch/i386/gdtoa/gd_qnan.h
===================================================================
RCS file: /cvs/src/lib/libc/arch/i386/gdtoa/gd_qnan.h,v
retrieving revision 1.1
diff -u -p -u -r1.1 gd_qnan.h
--- arch/i386/gdtoa/gd_qnan.h   7 Sep 2008 20:36:07 -0000       1.1
+++ arch/i386/gdtoa/gd_qnan.h   23 Apr 2018 23:41:20 -0000
@@ -1,12 +1,12 @@
-#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

Reply via email to