diff options
author | Joseph Myers <joseph@codesourcery.com> | 2012-05-04 10:44:39 +0000 |
---|---|---|
committer | Joseph Myers <joseph@codesourcery.com> | 2012-05-04 10:44:39 +0000 |
commit | 8f203e6cb695daa219f8148e81e108c2da8137d4 (patch) | |
tree | 1d4730fe5e620526011369c6b354f97521a2797a | |
parent | 5197d9c2b443eb6ae89ad9ae1eb8f655650d8d9f (diff) | |
download | glibc-8f203e6cb695daa219f8148e81e108c2da8137d4.zip glibc-8f203e6cb695daa219f8148e81e108c2da8137d4.tar.gz glibc-8f203e6cb695daa219f8148e81e108c2da8137d4.tar.bz2 |
Fix strtod rounding of hex values (bug 14049).
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | stdlib/strtod_l.c | 19 | ||||
-rw-r--r-- | stdlib/tst-strtod.c | 5 |
4 files changed, 28 insertions, 5 deletions
@@ -1,3 +1,10 @@ +2012-05-04 Joseph Myers <joseph@codesourcery.com> + + [BZ #14049] + * stdlib/strtod_l.c (____STRTOF_INTERNAL): Check for trailing + nonzero digits before rounding a hex value. + * stdlib/tst-strtod.c (tests): Add another test. + 2012-05-03 Andreas Krebbel <Andreas.Krebbel@de.ibm.com> * sysdeps/s390/fpu/libm-test-ulps: Update. @@ -23,7 +23,7 @@ Version 2.16 13872, 13873, 13879, 13883, 13886, 13892, 13895, 13908, 13910, 13911, 13912, 13913, 13915, 13916, 13917, 13918, 13919, 13920, 13921, 13924, 13926, 13927, 13928, 13938, 13941, 13942, 13963, 13967, 13970, 13973, - 14027, 14033, 14034, 14040, 14055 + 14027, 14033, 14034, 14040, 14049, 14055 * ISO C11 support: diff --git a/stdlib/strtod_l.c b/stdlib/strtod_l.c index 93ead75..2166a08 100644 --- a/stdlib/strtod_l.c +++ b/stdlib/strtod_l.c @@ -1,6 +1,5 @@ /* Convert string representing a number to float value, using given locale. - Copyright (C) 1997,1998,2002,2004,2005,2006,2007,2008,2009,2010,2011 - Free Software Foundation, Inc. + Copyright (C) 1997-2012 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -994,8 +993,20 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc) retval[idx--] |= val >> (4 - pos - 1); val <<= BITS_PER_MP_LIMB - (4 - pos - 1); if (idx < 0) - return round_and_return (retval, exponent, negative, val, - BITS_PER_MP_LIMB - 1, dig_no > 0); + { + int rest_nonzero = 0; + while (--dig_no > 0) + { + if (*startp != L_('0')) + { + rest_nonzero = 1; + break; + } + startp++; + } + return round_and_return (retval, exponent, negative, val, + BITS_PER_MP_LIMB - 1, rest_nonzero); + } retval[idx] = val; pos = BITS_PER_MP_LIMB - 1 - (4 - pos - 1); diff --git a/stdlib/tst-strtod.c b/stdlib/tst-strtod.c index 25bee78..738e73e 100644 --- a/stdlib/tst-strtod.c +++ b/stdlib/tst-strtod.c @@ -69,6 +69,11 @@ static const struct ltest tests[] = { "+InFiNiTy", HUGE_VAL, '\0', 0 }, { "0x80000Ap-23", 0x80000Ap-23, '\0', 0 }, { "1e-324", 0, '\0', ERANGE }, + { "0x100000000000008p0", 0x1p56, '\0', 0 }, + { "0x100000000000008.p0", 0x1p56, '\0', 0 }, + { "0x100000000000008.00p0", 0x1p56, '\0', 0 }, + { "0x10000000000000800p0", 0x1p64, '\0', 0 }, + { "0x10000000000000801p0", 0x1.0000000000001p64, '\0', 0 }, { NULL, 0, '\0', 0 } }; |