aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2013-11-13 12:59:54 +0000
committerJoseph Myers <joseph@codesourcery.com>2013-11-13 12:59:54 +0000
commit9310c284ae91f13247c9dd7ff58fc2683b9c523d (patch)
tree86478302002c020e38bc75f43abce8ecb37528b1
parent7a2ad8cf392acfcaef319e722dda9101d4d8b6bd (diff)
downloadglibc-9310c284ae91f13247c9dd7ff58fc2683b9c523d.zip
glibc-9310c284ae91f13247c9dd7ff58fc2683b9c523d.tar.gz
glibc-9310c284ae91f13247c9dd7ff58fc2683b9c523d.tar.bz2
Fix strtod rounding of half the least subnormal (bug 16151).
-rw-r--r--ChangeLog9
-rw-r--r--NEWS3
-rw-r--r--stdlib/strtod_l.c2
-rw-r--r--stdlib/tst-strtod-round-data8
-rw-r--r--stdlib/tst-strtod-round.c288
5 files changed, 308 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index f1e09b1..c05a9c6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2013-11-13 Joseph Myers <joseph@codesourcery.com>
+
+ [BZ #16151]
+ * stdlib/strtod_l.c (round_and_return): Do not consider
+ retval[RETURN_LIBM_SIZE - 1] when determining more_bits for an
+ exponent one less than half the least subnormal exponent.
+ * stdlib/test-strtod-round-data: Add more tests.
+ * stdlib/tst-strtod-round.c (tests): Regenerated.
+
2013-11-13 Adhemerval Zanella <azanella@linux.vnet.ibm.com>
[BZ #14143]
diff --git a/NEWS b/NEWS
index 3b44124..c6ec272 100644
--- a/NEWS
+++ b/NEWS
@@ -17,7 +17,8 @@ Version 2.19
15825, 15844, 15847, 15849, 15855, 15856, 15857, 15859, 15867, 15886,
15887, 15890, 15892, 15893, 15895, 15897, 15905, 15909, 15917, 15919,
15921, 15923, 15939, 15948, 15963, 15966, 15985, 15988, 16032, 16034,
- 16036, 16037, 16041, 16071, 16072, 16074, 16078, 16112, 16150, 16153.
+ 16036, 16037, 16041, 16071, 16072, 16074, 16078, 16112, 16150, 16151,
+ 16153.
* CVE-2012-4412 The strcoll implementation caches indices and rules for
large collation sequences to optimize multiple passes. This cache
diff --git a/stdlib/strtod_l.c b/stdlib/strtod_l.c
index 90541cd..c1c5c0d 100644
--- a/stdlib/strtod_l.c
+++ b/stdlib/strtod_l.c
@@ -228,7 +228,7 @@ round_and_return (mp_limb_t *retval, intmax_t exponent, int negative,
round_limb = retval[RETURN_LIMB_SIZE - 1];
round_bit = (MANT_DIG - 1) % BITS_PER_MP_LIMB;
- for (i = 0; i < RETURN_LIMB_SIZE; ++i)
+ for (i = 0; i < RETURN_LIMB_SIZE - 1; ++i)
more_bits |= retval[i] != 0;
MPN_ZERO (retval, RETURN_LIMB_SIZE);
}
diff --git a/stdlib/tst-strtod-round-data b/stdlib/tst-strtod-round-data
index 86d460e..a6c3767 100644
--- a/stdlib/tst-strtod-round-data
+++ b/stdlib/tst-strtod-round-data
@@ -109,3 +109,11 @@
-0x0.7p-1074
-0x0.7p-16445
-0x0.7p-16494
+0x1p-150
+0x1p-1075
+0x1p-16446
+0x1p-16495
+-0x1p-150
+-0x1p-1075
+-0x1p-16446
+-0x1p-16495
diff --git a/stdlib/tst-strtod-round.c b/stdlib/tst-strtod-round.c
index 9a44026..e7aaed1 100644
--- a/stdlib/tst-strtod-round.c
+++ b/stdlib/tst-strtod-round.c
@@ -7535,6 +7535,294 @@ static const struct test tests[] = {
-0x0p+0L,
-0x0p+0L,
-0x0p+0L),
+ TEST ("0x1p-150",
+ false,
+ 0x0p+0f,
+ 0x0p+0f,
+ 0x0p+0f,
+ 0x8p-152f,
+ true,
+ 0x4p-152,
+ 0x4p-152,
+ 0x4p-152,
+ 0x4p-152,
+ true,
+ 0x4p-152L,
+ 0x4p-152L,
+ 0x4p-152L,
+ 0x4p-152L,
+ true,
+ 0x4p-152L,
+ 0x4p-152L,
+ 0x4p-152L,
+ 0x4p-152L,
+ true,
+ 0x4p-152L,
+ 0x4p-152L,
+ 0x4p-152L,
+ 0x4p-152L,
+ true,
+ 0x4p-152L,
+ 0x4p-152L,
+ 0x4p-152L,
+ 0x4p-152L,
+ true,
+ 0x4p-152L,
+ 0x4p-152L,
+ 0x4p-152L,
+ 0x4p-152L),
+ TEST ("0x1p-1075",
+ false,
+ 0x0p+0f,
+ 0x0p+0f,
+ 0x0p+0f,
+ 0x8p-152f,
+ false,
+ 0x0p+0,
+ 0x0p+0,
+ 0x0p+0,
+ 0x4p-1076,
+ false,
+ 0x0p+0L,
+ 0x0p+0L,
+ 0x0p+0L,
+ 0x4p-1076L,
+ true,
+ 0x2p-1076L,
+ 0x2p-1076L,
+ 0x2p-1076L,
+ 0x2p-1076L,
+ true,
+ 0x2p-1076L,
+ 0x2p-1076L,
+ 0x2p-1076L,
+ 0x2p-1076L,
+ false,
+ 0x0p+0L,
+ 0x0p+0L,
+ 0x0p+0L,
+ 0x4p-1076L,
+ true,
+ 0x2p-1076L,
+ 0x2p-1076L,
+ 0x2p-1076L,
+ 0x2p-1076L),
+ TEST ("0x1p-16446",
+ false,
+ 0x0p+0f,
+ 0x0p+0f,
+ 0x0p+0f,
+ 0x8p-152f,
+ false,
+ 0x0p+0,
+ 0x0p+0,
+ 0x0p+0,
+ 0x4p-1076,
+ false,
+ 0x0p+0L,
+ 0x0p+0L,
+ 0x0p+0L,
+ 0x4p-1076L,
+ false,
+ 0x0p+0L,
+ 0x0p+0L,
+ 0x0p+0L,
+ 0x8p-16448L,
+ true,
+ 0x4p-16448L,
+ 0x4p-16448L,
+ 0x4p-16448L,
+ 0x4p-16448L,
+ false,
+ 0x0p+0L,
+ 0x0p+0L,
+ 0x0p+0L,
+ 0x4p-1076L,
+ true,
+ 0x4p-16448L,
+ 0x4p-16448L,
+ 0x4p-16448L,
+ 0x4p-16448L),
+ TEST ("0x1p-16495",
+ false,
+ 0x0p+0f,
+ 0x0p+0f,
+ 0x0p+0f,
+ 0x8p-152f,
+ false,
+ 0x0p+0,
+ 0x0p+0,
+ 0x0p+0,
+ 0x4p-1076,
+ false,
+ 0x0p+0L,
+ 0x0p+0L,
+ 0x0p+0L,
+ 0x4p-1076L,
+ false,
+ 0x0p+0L,
+ 0x0p+0L,
+ 0x0p+0L,
+ 0x8p-16448L,
+ false,
+ 0x0p+0L,
+ 0x0p+0L,
+ 0x0p+0L,
+ 0x4p-16448L,
+ false,
+ 0x0p+0L,
+ 0x0p+0L,
+ 0x0p+0L,
+ 0x4p-1076L,
+ false,
+ 0x0p+0L,
+ 0x0p+0L,
+ 0x0p+0L,
+ 0x4p-16496L),
+ TEST ("-0x1p-150",
+ false,
+ -0x8p-152f,
+ -0x0p+0f,
+ -0x0p+0f,
+ -0x0p+0f,
+ true,
+ -0x4p-152,
+ -0x4p-152,
+ -0x4p-152,
+ -0x4p-152,
+ true,
+ -0x4p-152L,
+ -0x4p-152L,
+ -0x4p-152L,
+ -0x4p-152L,
+ true,
+ -0x4p-152L,
+ -0x4p-152L,
+ -0x4p-152L,
+ -0x4p-152L,
+ true,
+ -0x4p-152L,
+ -0x4p-152L,
+ -0x4p-152L,
+ -0x4p-152L,
+ true,
+ -0x4p-152L,
+ -0x4p-152L,
+ -0x4p-152L,
+ -0x4p-152L,
+ true,
+ -0x4p-152L,
+ -0x4p-152L,
+ -0x4p-152L,
+ -0x4p-152L),
+ TEST ("-0x1p-1075",
+ false,
+ -0x8p-152f,
+ -0x0p+0f,
+ -0x0p+0f,
+ -0x0p+0f,
+ false,
+ -0x4p-1076,
+ -0x0p+0,
+ -0x0p+0,
+ -0x0p+0,
+ false,
+ -0x4p-1076L,
+ -0x0p+0L,
+ -0x0p+0L,
+ -0x0p+0L,
+ true,
+ -0x2p-1076L,
+ -0x2p-1076L,
+ -0x2p-1076L,
+ -0x2p-1076L,
+ true,
+ -0x2p-1076L,
+ -0x2p-1076L,
+ -0x2p-1076L,
+ -0x2p-1076L,
+ false,
+ -0x4p-1076L,
+ -0x0p+0L,
+ -0x0p+0L,
+ -0x0p+0L,
+ true,
+ -0x2p-1076L,
+ -0x2p-1076L,
+ -0x2p-1076L,
+ -0x2p-1076L),
+ TEST ("-0x1p-16446",
+ false,
+ -0x8p-152f,
+ -0x0p+0f,
+ -0x0p+0f,
+ -0x0p+0f,
+ false,
+ -0x4p-1076,
+ -0x0p+0,
+ -0x0p+0,
+ -0x0p+0,
+ false,
+ -0x4p-1076L,
+ -0x0p+0L,
+ -0x0p+0L,
+ -0x0p+0L,
+ false,
+ -0x8p-16448L,
+ -0x0p+0L,
+ -0x0p+0L,
+ -0x0p+0L,
+ true,
+ -0x4p-16448L,
+ -0x4p-16448L,
+ -0x4p-16448L,
+ -0x4p-16448L,
+ false,
+ -0x4p-1076L,
+ -0x0p+0L,
+ -0x0p+0L,
+ -0x0p+0L,
+ true,
+ -0x4p-16448L,
+ -0x4p-16448L,
+ -0x4p-16448L,
+ -0x4p-16448L),
+ TEST ("-0x1p-16495",
+ false,
+ -0x8p-152f,
+ -0x0p+0f,
+ -0x0p+0f,
+ -0x0p+0f,
+ false,
+ -0x4p-1076,
+ -0x0p+0,
+ -0x0p+0,
+ -0x0p+0,
+ false,
+ -0x4p-1076L,
+ -0x0p+0L,
+ -0x0p+0L,
+ -0x0p+0L,
+ false,
+ -0x8p-16448L,
+ -0x0p+0L,
+ -0x0p+0L,
+ -0x0p+0L,
+ false,
+ -0x4p-16448L,
+ -0x0p+0L,
+ -0x0p+0L,
+ -0x0p+0L,
+ false,
+ -0x4p-1076L,
+ -0x0p+0L,
+ -0x0p+0L,
+ -0x0p+0L,
+ false,
+ -0x4p-16496L,
+ -0x0p+0L,
+ -0x0p+0L,
+ -0x0p+0L),
};
static int