diff options
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | math/test-misc.c | 7 | ||||
-rw-r--r-- | stdio-common/Makefile | 2 | ||||
-rw-r--r-- | stdio-common/tst-sprintf2.c | 59 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-128ibm/printf_fphex.c | 35 |
5 files changed, 96 insertions, 18 deletions
diff --git a/ChangeLog b/ChangeLog index 18c2df3dbf..5845b8a951 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2007-06-04 Jakub Jelinek <jakub@redhat.com> + + * sysdeps/ieee754/ldbl-128ibm/printf_fphex.c + (PRINT_FPHEX_LONG_DOUBLE): Fix printing numbers where lower double + is non-zero, but smaller than 2 * __DBL_MIN__. + * stdio-common/tst-sprintf2.c: New test. + * stdio-common/Makefile (tests): Add tst-sprintf2. + + * math/test-misc.c (main): Don't run last batch of tests with + IBM long double format. + 2007-05-31 Steven Munroe <sjmunroe@us.ibm.com> * sysdeps/powerpc/powerpc32/970/fpu/Implies: New file. diff --git a/math/test-misc.c b/math/test-misc.c index a1ad6885db..14fe38b90a 100644 --- a/math/test-misc.c +++ b/math/test-misc.c @@ -1235,7 +1235,12 @@ main (void) } #endif -#if !defined NO_LONG_DOUBLE && LDBL_MANT_DIG >= DBL_MANT_DIG + 4 +/* Skip testing IBM long double format, for 2 reasons: + 1) it only supports FE_TONEAREST + 2) nextafter (0.0, 1.0) == nextafterl (0.0L, 1.0L), so + nextafter (0.0, 1.0) / 16.0L will be 0.0L. */ +#if !defined NO_LONG_DOUBLE && LDBL_MANT_DIG >= DBL_MANT_DIG + 4 \ + && LDBL_MANT_DIG != 106 int oldmode = fegetround (); int j; for (j = 0; j < 4; j++) diff --git a/stdio-common/Makefile b/stdio-common/Makefile index 709a5730fb..735b40104a 100644 --- a/stdio-common/Makefile +++ b/stdio-common/Makefile @@ -54,7 +54,7 @@ tests := tstscanf test_rdwr test-popen tstgetln test-fseek \ tst-swprintf tst-fseek tst-fmemopen test-vfprintf tst-gets \ tst-perror tst-sprintf tst-rndseek tst-fdopen tst-fphex bug14 bug15 \ tst-popen tst-unlockedio tst-fmemopen2 tst-put-error tst-fgets \ - tst-fwrite bug16 bug17 tst-swscanf + tst-fwrite bug16 bug17 tst-swscanf tst-sprintf2 test-srcs = tst-unbputc tst-printf diff --git a/stdio-common/tst-sprintf2.c b/stdio-common/tst-sprintf2.c new file mode 100644 index 0000000000..9024b58782 --- /dev/null +++ b/stdio-common/tst-sprintf2.c @@ -0,0 +1,59 @@ +#include <float.h> +#include <math.h> +#include <stdio.h> + +int +main (void) +{ + volatile union { long double l; long long x[2]; } u; + char buf[64]; + int result = 0; + +#define TEST(val) \ + do \ + { \ + u.l = (val); \ + snprintf (buf, sizeof buf, "%LaL", u.l); \ + if (strcmp (buf, #val) != 0) \ + { \ + printf ("Error on line %d: %s != %s\n", __LINE__, buf, #val); \ + result = 1; \ + } \ + /* printf ("%s %La %016Lx %016Lx\n", #val, u.l, u.x[0], u.x[1]); */ \ + } \ + while (0) + +#if LDBL_MANT_DIG >= 106 +# if LDBL_MANT_DIG == 106 + TEST (0x0.ffffffffffffp-1022L); + TEST (0x0.ffffffffffff1p-1022L); + TEST (0x0.fffffffffffffp-1022L); +# endif + TEST (0x1p-1022L); + TEST (0x1.0000000000001p-1022L); + TEST (0x1.00000000001e7p-1022L); + TEST (0x1.fffffffffffffp-1022L); + TEST (0x1p-1021L); + TEST (0x1.00000000000008p-1021L); + TEST (0x1.0000000000001p-1021L); + TEST (0x1.00000000000018p-1021L); + TEST (0x1.0000000000000f8p-1017L); + TEST (0x1.0000000000001p-1017L); + TEST (0x1.000000000000108p-1017L); + TEST (0x1.000000000000dcf8p-1013L); + TEST (0x1.000000000000ddp-1013L); + TEST (0x1.000000000000dd08p-1013L); + TEST (0x1.ffffffffffffffffffffffffffp-1L); + TEST (0x1.ffffffffffffffffffffffffff8p-1L); + TEST (0x1p+0L); + TEST (0x1.000000000000000000000000008p+0L); + TEST (0x1.00000000000000000000000001p+0L); + TEST (0x1.000000000000000000000000018p+0L); + TEST (0x1.23456789abcdef123456789abc8p+0L); + TEST (0x1.23456789abcde7123456789abc8p+0L); + TEST (0x1.23456789abcdef123456789abc8p+64L); + TEST (0x1.23456789abcde7123456789abc8p+64L); + TEST (0x1.123456789abcdef123456789p-969L); +#endif + return result; +} diff --git a/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c b/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c index 2a7b70fabf..b2ad25e31f 100644 --- a/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c +++ b/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c @@ -1,5 +1,5 @@ /* Print floating point number in hexadecimal notation according to ISO C99. - Copyright (C) 1997,1998,1999,2000,2001,2002,2004,2006 + Copyright (C) 1997,1998,1999,2000,2001,2002,2004,2006,2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -35,21 +35,24 @@ do { \ \ lo = ((long long)eldbl.ieee.mantissa2 << 32) | eldbl.ieee.mantissa3; \ hi = ((long long)eldbl.ieee.mantissa0 << 32) | eldbl.ieee.mantissa1; \ - /* If the lower double is not a denomal or zero then set the hidden \ - 53rd bit. */ \ - if (eldbl.ieee.exponent2 > 0x001) \ - { \ - lo |= (1ULL << 52); \ - lo = lo << 7; /* pre-shift lo to match ieee854. */ \ - /* The lower double is normalized separately from the upper. We \ - may need to adjust the lower manitissa to reflect this. */ \ - ediff = eldbl.ieee.exponent - eldbl.ieee.exponent2; \ - if (ediff > 53) \ - lo = lo >> (ediff-53); \ - } \ - \ - if ((eldbl.ieee.negative != eldbl.ieee.negative2) \ - && ((eldbl.ieee.exponent2 != 0) && (lo != 0L))) \ + lo <<= 7; /* pre-shift lo to match ieee854. */ \ + /* If the lower double is not a denomal or zero then set the hidden \ + 53rd bit. */ \ + if (eldbl.ieee.exponent2 != 0) \ + lo |= (1ULL << (52 + 7)); \ + else \ + lo <<= 1; \ + /* The lower double is normalized separately from the upper. We \ + may need to adjust the lower manitissa to reflect this. */ \ + ediff = eldbl.ieee.exponent - eldbl.ieee.exponent2; \ + if (ediff > 53 + 63) \ + lo = 0; \ + else if (ediff > 53) \ + lo = lo >> (ediff - 53); \ + else if (eldbl.ieee.exponent2 == 0 && ediff < 53) \ + lo = lo << (53 - ediff); \ + if (eldbl.ieee.negative != eldbl.ieee.negative2 \ + && (eldbl.ieee.exponent2 != 0 || lo != 0L)) \ { \ lo = (1ULL << 60) - lo; \ if (hi == 0L) \ |