changeset 46:38cf7fa65976

sprintf/float.c: rounding corner case bug
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 29 Sep 2017 03:23:01 +0000
parents a2d5d622e19e
children 3ba0351942e1
files sprintf/float.c
diffstat 1 files changed, 13 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/sprintf/float.c	Fri Sep 29 03:02:50 2017 +0000
+++ b/sprintf/float.c	Fri Sep 29 03:23:01 2017 +0000
@@ -43,6 +43,10 @@
 			if (++*end <= '9')
 				break;
 			*end = '0';
+			if (end == start) {
+				*--end = '1';
+				return(1);
+			}
 		}
 	/* ``"%.3f", (double)-0.0004'' gives you a negative 0. */
 	else if (sign == '-')
@@ -52,7 +56,7 @@
 			if (*end != '0')
 				break;
 			if (end == start)
-				return(1);	/* clear the -ve */
+				return(-1);	/* clear the -ve */
 		}
 	return(0);
 }
@@ -64,6 +68,7 @@
 	char buf[MAX_INT_DIGITS + 1 + MAXFRACT];
 	int extra_prec = 0;
 	int origsign = sign;
+	int round_stat;
 	double fract, tmp;
 	char *start, *t;
 
@@ -104,8 +109,13 @@
 				fract = modf(fract * 10, &tmp);
 				*t++ = tochar((int)tmp);
 			} while (--prec && fract);
-		if (fract && f_round(fract, start, t - 1, sign))
-			sign = origsign;
+		if (fract) {
+			round_stat = f_round(fract, start, t - 1, sign);
+			if (round_stat == 1)
+				start--;
+			else if (round_stat == -1)
+				sign = origsign;
+		}
 	}
 	return _sprintf_field(op, width, flags, sign, start, t - start,
 				0, prec + extra_prec);