This is the mail archive of the libc-hacker@sourceware.cygnus.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

long double bug


Hi all,

I've found a bug in libc 2.0.6 and libc 2.0.108.  The problem affects all
architectures where sizeof(double) is sizeof(long double) or more exactly
all architectures where long double doesn't have the same properties as on
i386 and m68k.  For these architectures glibc will make the same
assumptions about the size of the various fields in a IEEE 754 float as
they are true for example on i386 or m68k resulting in extremly bad
precission for long double arithmetic.  The two functions that I know of
which are affected are strtold() and the ``%Lf'' format of scanf.

Below the quickfix for MIPS which I'm using.  Ulrich probably wants
something more elegant - and he's right ...  What this quickfix doesn't fix
is sysdeps/ieee754/ieee754.h.  If I understand the philosophy of IEEE 754
right then we should probably change the definitions names into
ieee754_single ieee754_double and ieee854_extended and provide aliases
ieee754_float, ieee754_double and ieee854_long_double as apropriate for an
architecture - we also don't deal with single precission only FPUs which
some MIPS are?

  Ralf

diff -urN glibc-2.0.6.alt/ChangeLog glibc-2.0.6/ChangeLog
--- glibc-2.0.6.alt/ChangeLog	Tue Dec 22 18:52:04 1998
+++ glibc-2.0.6/ChangeLog	Thu Dec 24 18:25:48 1998
@@ -1,3 +1,13 @@
+1998-12-24  18:24 Ralf Baechle  <ralf@gnu.org>
+
+	* stdlib/fpioconst.c: Fix for CPUs without extended precission. 
+	* stdlib/fpioconst.h: Likewise.
+
+	* sysdeps/mips/dbl2mpn.c: New File.
+	* sysdeps/mips/ldbl2mpn.c: New File.
+	* sysdeps/mips/mpn2dbl.c: New File.
+	* sysdeps/mips/mpn2ldbl.c: New file.
+
 1998-12-22 18:44  Ralf Baechle  <ralf@gnu.org>
 
 	* elf/ldconfig.c: Delete; ldconfig comes now in a separate package.
diff -urN glibc-2.0.6.alt/stdlib/fpioconst.c glibc-2.0.6/stdlib/fpioconst.c
--- glibc-2.0.6.alt/stdlib/fpioconst.c	Mon Feb 10 04:18:46 1997
+++ glibc-2.0.6/stdlib/fpioconst.c	Thu Dec 24 00:15:24 1998
@@ -54,6 +54,7 @@
     0xd8d99f72, 0x12152f87, 0x6bde50c6, 0xcf4a6e70, 0xd595d80f, 0x26b2716e,
     0xadc666b0, 0x1d153624, 0x3c42d35a, 0x63ff540e, 0xcc5573c0, 0x65f9ef17,
     0x55bc28f2, 0x80dcc7f7, 0xf46eeddc, 0x5fdcefce, 0x000553f7 };
+#ifndef __mips__
 static const mp_limb_t _ten_p9[] =
   { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -195,9 +196,13 @@
     0xd868b275, 0x8bd2b496, 0x1c5563f4, 0xc234d8f5, 0xf868e970, 0xf9151fff,
     0xae7be4a2, 0x271133ee, 0xbb0fd922, 0x25254932, 0xa60a9fc0, 0x104bcd64,
     0x30290145, 0x00000062 };
-
 /* This value is the index of the last array element.  */
 #define _LAST_POW10	12
+#else
+/* This value is the index of the last array element.  */
+#define _LAST_POW10	8
+#endif
+
 
 #elif BITS_PER_MP_LIMB == 64
 
@@ -228,6 +233,7 @@
     0x12152f87d8d99f72, 0xcf4a6e706bde50c6, 0x26b2716ed595d80f,
     0x1d153624adc666b0, 0x63ff540e3c42d35a, 0x65f9ef17cc5573c0,
     0x80dcc7f755bc28f2, 0x5fdcefcef46eeddc, 0x00000000000553f7 };
+#ifndef __mips__
 static const mp_limb_t _ten_p9[] =
   { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
     0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
@@ -372,6 +378,11 @@
 
 /* This value is the index of the last array element.  */
 #define _LAST_POW10	12
+#else
+/* This value is the index of the last array element.  */
+#define _LAST_POW10	8
+#endif
+
 
 #else
 #  error "mp_limb_t size " BITS_PER_MP_LIMB "not accounted for"
@@ -392,10 +403,12 @@
     { _ten_p6, sizeof (_ten_p6) / sizeof (_ten_p6[0]),		213,	 210 },
     { _ten_p7, sizeof (_ten_p7) / sizeof (_ten_p7[0]),		426,	 422 },
     { _ten_p8, sizeof (_ten_p8) / sizeof (_ten_p8[0]),	  	851,	 848 },
+#ifndef __mips__
     { _ten_p9, sizeof (_ten_p9) / sizeof (_ten_p9[0]),	 	1701,	1698 },
     { _ten_p10, sizeof (_ten_p10) / sizeof (_ten_p10[0]),	3402,	3399 },
     { _ten_p11, sizeof (_ten_p11) / sizeof (_ten_p11[0]),	6804,	6800 },
     { _ten_p12, sizeof (_ten_p12) / sizeof (_ten_p12[0]), 	13607, 13604 }
+#endif
   };
 
 #if LAST_POW10 > _LAST_POW10
diff -urN glibc-2.0.6.alt/stdlib/fpioconst.h glibc-2.0.6/stdlib/fpioconst.h
--- glibc-2.0.6.alt/stdlib/fpioconst.h	Mon Feb 10 04:18:47 1997
+++ glibc-2.0.6/stdlib/fpioconst.h	Thu Dec 24 00:12:34 1998
@@ -32,7 +32,11 @@
    XXX These should be defined in <float.h>.  For the time being, we have the
    IEEE754 values here.  */
 
+#if LDBL_MAX_10_EXP == 308
+#define LDBL_MAX_10_EXP_LOG	8 /* = floor(log_2(LDBL_MAX_10_EXP)) */
+#else
 #define LDBL_MAX_10_EXP_LOG	12 /* = floor(log_2(LDBL_MAX_10_EXP)) */
+#endif
 #define DBL_MAX_10_EXP_LOG	8 /* = floor(log_2(DBL_MAX_10_EXP)) */
 #define FLT_MAX_10_EXP_LOG	5 /* = floor(log_2(FLT_MAX_10_EXP)) */
 
diff -urN glibc-2.0.6.alt/sysdeps/mips/dbl2mpn.c glibc-2.0.6/sysdeps/mips/dbl2mpn.c
--- glibc-2.0.6.alt/sysdeps/mips/dbl2mpn.c	Thu Jan  1 01:00:00 1970
+++ glibc-2.0.6/sysdeps/mips/dbl2mpn.c	Thu Dec 24 00:00:39 1998
@@ -0,0 +1,25 @@
+/*
+   Copyright (C) 1998 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <sysdeps/ieee754/dbl2mpn.c>
+
+/* On MIPS `long double' is the same thing as `double' therefore this is
+   just an alias.  */
+
+strong_alias(__mpn_extract_double, __mpn_extract_long_double)
diff -urN glibc-2.0.6.alt/sysdeps/mips/ldbl2mpn.c glibc-2.0.6/sysdeps/mips/ldbl2mpn.c
--- glibc-2.0.6.alt/sysdeps/mips/ldbl2mpn.c	Thu Jan  1 01:00:00 1970
+++ glibc-2.0.6/sysdeps/mips/ldbl2mpn.c	Thu Dec 24 00:01:40 1998
@@ -0,0 +1,21 @@
+/*
+   Copyright (C) 1998 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* On MIPS `long double' is the same thing as `double' therefore this is
+   just an alias defined in dbl2mpn.c.  */
diff -urN glibc-2.0.6.alt/sysdeps/mips/mpn2dbl.c glibc-2.0.6/sysdeps/mips/mpn2dbl.c
--- glibc-2.0.6.alt/sysdeps/mips/mpn2dbl.c	Thu Jan  1 01:00:00 1970
+++ glibc-2.0.6/sysdeps/mips/mpn2dbl.c	Thu Dec 24 00:00:33 1998
@@ -0,0 +1,22 @@
+/*
+   Copyright (C) 1998 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <sysdeps/ieee754/mpn2dbl.c>
+
+strong_alias(__mpn_construct_double, __mpn_construct_long_double)
diff -urN glibc-2.0.6.alt/sysdeps/mips/mpn2ldbl.c glibc-2.0.6/sysdeps/mips/mpn2ldbl.c
--- glibc-2.0.6.alt/sysdeps/mips/mpn2ldbl.c	Thu Jan  1 01:00:00 1970
+++ glibc-2.0.6/sysdeps/mips/mpn2ldbl.c	Thu Dec 24 00:02:37 1998
@@ -0,0 +1,20 @@
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* On MIPS `long double' is the same thing as `double' therefore this is
+   just an alias defined in mpn2dbl.c.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]