summaryrefslogtreecommitdiff
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
parent5197d9c2b443eb6ae89ad9ae1eb8f655650d8d9f (diff)
downloadglibc-8f203e6cb695daa219f8148e81e108c2da8137d4.tar.gz
Fix strtod rounding of hex values (bug 14049).
-rw-r--r--ChangeLog7
-rw-r--r--NEWS2
-rw-r--r--stdlib/strtod_l.c19
-rw-r--r--stdlib/tst-strtod.c5
4 files changed, 28 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index 8c98f0171e..447d4a0f9e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/NEWS b/NEWS
index 218319712f..0873b2f03d 100644
--- a/NEWS
+++ b/NEWS
@@ -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 93ead7533c..2166a08d21 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 25bee78f2e..738e73ebba 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 }
};