summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSzabolcs Nagy <nsz@port70.net>2016-09-04 04:46:00 +0200
committerRich Felker <dalias@aerifal.cx>2016-10-20 13:29:09 -0400
commitd184a09e0529f33d8ddddb8825039133483a2c41 (patch)
treeefccccc90b44504aa5ed2b04cd0cf15e1b291a80
parentf33b17585058381491e6fda08f491b8e48c7980c (diff)
downloadmusl-d184a09e0529f33d8ddddb8825039133483a2c41.tar.gz
musl-d184a09e0529f33d8ddddb8825039133483a2c41.tar.bz2
musl-d184a09e0529f33d8ddddb8825039133483a2c41.tar.xz
musl-d184a09e0529f33d8ddddb8825039133483a2c41.zip
fix strtod and strtof rounding with many trailing zeros
in certain cases excessive trailing zeros could cause incorrect rounding from long double to double or float in decfloat. e.g. in strtof("9444733528689243848704.000000", 0) the argument is 0x1.000001p+73, exactly halfway between two representible floats, this incorrectly got rounded to 0x1.000002p+73 instead of 0x1p+73, but with less trailing 0 the rounding was fine. the fix makes sure that the z index always points one past the last non-zero digit in the base 10^9 representation, this way trailing zeros don't affect the rounding logic.
-rw-r--r--src/internal/floatscan.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/src/internal/floatscan.c b/src/internal/floatscan.c
index eef70df9..80305ee6 100644
--- a/src/internal/floatscan.c
+++ b/src/internal/floatscan.c
@@ -172,6 +172,9 @@ static long double decfloat(FILE *f, int c, int bits, int emin, int sign, int po
return sign * (long double)x[0] * p10s[rp-10];
}
+ /* Drop trailing zeros */
+ for (; !x[z-1]; z--);
+
/* Align radix point to B1B digit boundary */
if (rp % 9) {
int rpm9 = rp>=0 ? rp%9 : rp%9+9;