From 9310c284ae91f13247c9dd7ff58fc2683b9c523d Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Wed, 13 Nov 2013 12:59:54 +0000 Subject: Fix strtod rounding of half the least subnormal (bug 16151). --- stdlib/strtod_l.c | 2 +- stdlib/tst-strtod-round-data | 8 ++ stdlib/tst-strtod-round.c | 288 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 297 insertions(+), 1 deletion(-) (limited to 'stdlib') diff --git a/stdlib/strtod_l.c b/stdlib/strtod_l.c index 90541cd48f..c1c5c0db4e 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 86d460e3b6..a6c37677eb 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 9a440264d0..e7aaed17e8 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 -- cgit v1.2.1