aboutsummaryrefslogtreecommitdiff
path: root/stdlib
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2012-05-04 10:44:39 +0000
committerJoseph Myers <joseph@codesourcery.com>2012-05-04 10:44:39 +0000
commit8f203e6cb695daa219f8148e81e108c2da8137d4 (patch)
tree1d4730fe5e620526011369c6b354f97521a2797a /stdlib
parent5197d9c2b443eb6ae89ad9ae1eb8f655650d8d9f (diff)
downloadglibc-8f203e6cb695daa219f8148e81e108c2da8137d4.zip
glibc-8f203e6cb695daa219f8148e81e108c2da8137d4.tar.gz
glibc-8f203e6cb695daa219f8148e81e108c2da8137d4.tar.bz2
Fix strtod rounding of hex values (bug 14049).
Diffstat (limited to 'stdlib')
-rw-r--r--stdlib/strtod_l.c19
-rw-r--r--stdlib/tst-strtod.c5
2 files changed, 20 insertions, 4 deletions
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 }
};