From: Joseph Myers Date: Wed, 13 Nov 2013 12:59:54 +0000 (+0000) Subject: Fix strtod rounding of half the least subnormal (bug 16151). X-Git-Tag: glibc-2.19~522 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9310c284ae91f13247c9dd7ff58fc2683b9c523d;p=thirdparty%2Fglibc.git Fix strtod rounding of half the least subnormal (bug 16151). --- diff --git a/ChangeLog b/ChangeLog index f1e09b1a7ef..c05a9c6143c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2013-11-13 Joseph Myers + + [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 [BZ #14143] diff --git a/NEWS b/NEWS index 3b441241d65..c6ec27274a7 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 90541cd48fa..c1c5c0db4e9 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 86d460e3b6f..a6c37677eb3 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 9a440264d0d..e7aaed17e8f 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