This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH] Increase internal precision of ldbl-128ibm decimal printf
- From: "Paul E. Murphy" <murphyp at linux dot vnet dot ibm dot com>
- To: "libc-alpha at sourceware dot org" <libc-alpha at sourceware dot org>
- Cc: Tulio Magno Quites Machado Filho <tuliom at linux dot vnet dot ibm dot com>
- Date: Thu, 17 Mar 2016 16:41:02 -0500
- Subject: [PATCH] Increase internal precision of ldbl-128ibm decimal printf
- Authentication-results: sourceware.org; auth=none
When the signs differ, the precision of the conversion
could drop below 106 bits. This strategy is
identical to the hexadecimal variant.
0x1.ffffffffffffffffffffffffff80p111L is an example of
a number which should, but does not round trip through
printf as a decimal number when printing with 32 digits
of precision.
Note, the printf test did not pick this up, as it
only tests up to 30 digits. Long double can have
more at nominal precision.
2016-03-17 Paul E. Murphy <murphyp@linux.vnet.ibm.com>
* sysdeps/ieee754/ldbl-128ibm/ldbl2pm.c:
(__mpn_extract_long_double): Carry 7 extra intermediate
bits of precision to aide computing difference when
signs differ.
---
sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c | 21 +++++++++++++--------
1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c b/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c
index 4f550ef..afe6cf2 100644
--- a/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c
+++ b/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c
@@ -45,12 +45,17 @@ __mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size,
lo = ((long long) u.d[1].ieee.mantissa0 << 32) | u.d[1].ieee.mantissa1;
hi = ((long long) u.d[0].ieee.mantissa0 << 32) | u.d[0].ieee.mantissa1;
+ /* Hold 7 extra bits of precision in the mantissa. This allows
+ the normalizing shifts below to prevent losing precision when
+ the signs differ and the exponents are sufficiently far apart. */
+ lo <<= 7;
+
/* If the lower double is not a denormal or zero then set the hidden
53rd bit. */
if (u.d[1].ieee.exponent != 0)
- lo |= 1ULL << 52;
+ lo |= 1ULL << (52 + 7);
else
- lo = lo << 1;
+ lo = lo << (1 + 7);
/* The lower double is normalized separately from the upper. We may
need to adjust the lower manitissa to reflect this. */
@@ -72,12 +77,12 @@ __mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size,
if (u.d[0].ieee.negative != u.d[1].ieee.negative
&& lo != 0)
{
- lo = (1ULL << 53) - lo;
+ lo = (1ULL << (53 + 7)) - lo;
if (hi == 0)
{
/* we have a borrow from the hidden bit, so shift left 1. */
- hi = 0x0ffffffffffffeLL | (lo >> 51);
- lo = 0x1fffffffffffffLL & (lo << 1);
+ hi = 0x000ffffffffffffeLL | (lo >> (52 + 7));
+ lo = 0x0fffffffffffffffLL & (lo << 1);
(*expt)--;
}
else
@@ -85,14 +90,14 @@ __mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size,
}
#if BITS_PER_MP_LIMB == 32
/* Combine the mantissas to be contiguous. */
- res_ptr[0] = lo;
- res_ptr[1] = (hi << (53 - 32)) | (lo >> 32);
+ res_ptr[0] = lo >> 7;
+ res_ptr[1] = (hi << (53 - 32)) | (lo >> (32 + 7));
res_ptr[2] = hi >> 11;
res_ptr[3] = hi >> (32 + 11);
#define N 4
#elif BITS_PER_MP_LIMB == 64
/* Combine the two mantissas to be contiguous. */
- res_ptr[0] = (hi << 53) | lo;
+ res_ptr[0] = (hi << 53) | (lo >> 7);
res_ptr[1] = hi >> 11;
#define N 2
#else
--
2.4.3