Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [day] [month] [year] [list]
Date: Sun, 4 Sep 2016 04:46:00 +0200
From: Szabolcs Nagy <nsz@...t70.net>
To: musl@...ts.openwall.com
Subject: [PATCH] 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.
---
i think x[z-1] is fine in the loop here as z>0 and x[0]!=0
and later code does not turn x[z-1] into 0.

the upscaling code path already removed trailing zeros but
that was not always taken.

only tested on x86, the bad rounding cases depend on long double
representation.

 src/internal/floatscan.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/internal/floatscan.c b/src/internal/floatscan.c
index 17d8e70..66d01ef 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;
-- 
2.9.3

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.