public inbox for libc-hacker@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] Fix *printf %La with IBM long double format
@ 2007-06-04 13:00 Jakub Jelinek
  2007-06-06 13:28 ` Steven Munroe
  0 siblings, 1 reply; 2+ messages in thread
From: Jakub Jelinek @ 2007-06-04 13:00 UTC (permalink / raw)
  To: Ulrich Drepper, Steven Munroe; +Cc: Glibc hackers

Hi!

As the attached testcase shows, printf_fphex for ldbl-128ibm
has a bunch of issues when the lower double is denormal or has exponent 1.
E.g. the implicit mantissa bit needs to be also set for exponent 1,
the difference between exponents might be smaller than 53 (when the
smaller double is denormal and the bigger double has exponent less than
53, etc.

I've also included the unrelated workaround for test-misc.c failures
- the tests from 2007-05-03 aren't really testable on ppc/ppc64.

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.

--- libc/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c.jj	2006-01-28 01:07:25.000000000 +0100
+++ libc/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c	2007-06-04 14:02:12.000000000 +0200
@@ -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)							      \
--- libc/stdio-common/Makefile.jj	2007-03-19 17:43:12.000000000 +0100
+++ libc/stdio-common/Makefile	2007-06-04 14:05:02.000000000 +0200
@@ -54,7 +54,7 @@ tests := tstscanf test_rdwr test-popen t
 	 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
 
--- libc/stdio-common/tst-sprintf2.c.jj	2007-06-04 14:03:18.000000000 +0200
+++ libc/stdio-common/tst-sprintf2.c	2007-06-04 14:04:35.000000000 +0200
@@ -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;
+}
--- libc/math/test-misc.c.jj	2007-05-24 16:41:05.000000000 +0200
+++ libc/math/test-misc.c	2007-06-01 18:28:29.000000000 +0200
@@ -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++)

	Jakub

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

* Re: [PATCH] Fix *printf %La with IBM long double format
  2007-06-04 13:00 [PATCH] Fix *printf %La with IBM long double format Jakub Jelinek
@ 2007-06-06 13:28 ` Steven Munroe
  0 siblings, 0 replies; 2+ messages in thread
From: Steven Munroe @ 2007-06-06 13:28 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Ulrich Drepper, Glibc hackers, Ryan Arnold

Jakub Jelinek wrote:
> Hi!
>
> As the attached testcase shows, printf_fphex for ldbl-128ibm
> has a bunch of issues when the lower double is denormal or has exponent 1.
> E.g. the implicit mantissa bit needs to be also set for exponent 1,
> the difference between exponents might be smaller than 53 (when the
> smaller double is denormal and the bigger double has exponent less than
> 53, etc.
>
>   
I spotted this while debugging nextafterl and put it on the list for
Ryan to look at. But you got there first

Unfortunately I have been busy with POWER6 perf tuning issues...
> I've also included the unrelated workaround for test-misc.c failures
> - the tests from 2007-05-03 aren't really testable on ppc/ppc64.
>   

Thanks!

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

end of thread, other threads:[~2007-06-06 13:28 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-06-04 13:00 [PATCH] Fix *printf %La with IBM long double format Jakub Jelinek
2007-06-06 13:28 ` Steven Munroe

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