diff options
author | Paul E. Murphy <murphyp@linux.vnet.ibm.com> | 2016-02-29 13:27:36 -0600 |
---|---|---|
committer | Paul E. Murphy <murphyp@linux.vnet.ibm.com> | 2016-03-31 12:14:33 -0500 |
commit | 37a4c70bd4c5c74ac562072e450dc02e8cb4c150 (patch) | |
tree | c9a631e747dcb7ca4213c93460d7e45d153a0771 /stdio-common | |
parent | 830566307f038387ca0af3fd327706a8d1a2f595 (diff) | |
download | glibc-37a4c70bd4c5c74ac562072e450dc02e8cb4c150.tar.gz glibc-37a4c70bd4c5c74ac562072e450dc02e8cb4c150.tar.xz glibc-37a4c70bd4c5c74ac562072e450dc02e8cb4c150.zip |
Increase internal precision of ldbl-128ibm decimal printf [BZ #19853]
When the signs differ, the precision of the conversion sometimes drops below 106 bits. This strategy is identical to the hexadecimal variant. I've refactored tst-sprintf3 to enable testing a value with more than 30 significant digits in order to demonstrate this failure and its solution. Additionally, this implicitly fixes a typo in the shift quantities when subtracting from the high mantissa to compute the difference.
Diffstat (limited to 'stdio-common')
-rw-r--r-- | stdio-common/tst-sprintf3.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/stdio-common/tst-sprintf3.c b/stdio-common/tst-sprintf3.c index cffd1b69d0..dad216b941 100644 --- a/stdio-common/tst-sprintf3.c +++ b/stdio-common/tst-sprintf3.c @@ -38,11 +38,11 @@ do_test (void) # define COMPARE_LDBL(u, v) ((u).l == (v).l) #endif -#define TEST(val) \ +#define TEST_N(val, n) \ do \ { \ u.l = (val); \ - snprintf (buf, sizeof buf, "%.30LgL", u.l); \ + snprintf (buf, sizeof buf, "%." #n "LgL", u.l); \ if (strcmp (buf, #val) != 0) \ { \ printf ("Error on line %d: %s != %s\n", __LINE__, buf, #val); \ @@ -50,19 +50,25 @@ do_test (void) } \ if (sscanf (#val, "%Lg", &v.l) != 1 || !COMPARE_LDBL (u, v)) \ { \ - printf ("Error sscanf on line %d: %.30Lg != %.30Lg\n", __LINE__, \ - u.l, v.l); \ + printf ("Error sscanf on line %d: %." #n "Lg != %." #n "Lg\n", \ + __LINE__, u.l, v.l); \ result = 1; \ } \ /* printf ("%s %Lg %016Lx %016Lx\n", #val, u.l, u.x[0], u.x[1]); */ \ } \ while (0) +#define TEST(val) TEST_N (val,30) + #if LDBL_MANT_DIG >= 106 # if LDBL_MANT_DIG == 106 TEST (2.22507385850719347803989925739e-308L); TEST (2.22507385850719397210554509863e-308L); TEST (2.22507385850720088902458687609e-308L); + + /* Verify precision is not lost for long doubles + of the form +1.pN,-1.pM. */ + TEST_N (3.32306998946228968225951765070082e+35L, 34); # endif TEST (2.22507385850720138309023271733e-308L); TEST (2.22507385850720187715587855858e-308L); |