diff options
author | bde <bde@FreeBSD.org> | 1995-03-12 13:26:49 +0000 |
---|---|---|
committer | bde <bde@FreeBSD.org> | 1995-03-12 13:26:49 +0000 |
commit | 498e010b3a0e93a1ea7e9cf4db9e4736ffb84c5b (patch) | |
tree | 36540ff6c0d4d497e5f15d84c999123d84dda984 | |
parent | 3fefa68386316c4160eb85a42c3b79b7b89f62a7 (diff) | |
download | FreeBSD-src-498e010b3a0e93a1ea7e9cf4db9e4736ffb84c5b.zip FreeBSD-src-498e010b3a0e93a1ea7e9cf4db9e4736ffb84c5b.tar.gz |
Obtained from: 1.1.5. Originally by jtc. Cosmetically changed for this
commit by bde.
Fix bugs in floating point formatting. The 4.4lite version is similar
to revision 1.3 in old-cvs and is missing all of jtc's fixes in revision
1.4 in old-cvs. Revision 1.2 in ncvs fixed one of the old bugs but
introduced at least one new one (for %.0e).
old-cvs log:
revision 1.4
date: 1993/11/04 19:38:22; author: jtc; state: Exp; lines: +33 -20
My work from NetBSD to make printf() & friends ANSI C compliant.
Fixes several bugs in floating point formatting:
1. Trailing zeros were being stripped with %e format.
2. %g/%G formats incorrect.
3. Lots of other nits.
-rw-r--r-- | lib/libc/stdio/vfprintf.c | 38 |
1 files changed, 23 insertions, 15 deletions
diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c index ebd772f..65a1eb4 100644 --- a/lib/libc/stdio/vfprintf.c +++ b/lib/libc/stdio/vfprintf.c @@ -502,19 +502,20 @@ reswitch: switch (ch) { base = 10; goto number; #ifdef FLOATING_POINT - case 'e': /* anomalous precision */ + case 'e': case 'E': - prec = (prec == -1) ? - DEFPREC + 1 : prec + 1; - /* FALLTHROUGH */ - case 'f': /* always print trailing zeroes */ - if (prec != 0) - flags |= ALT; + case 'f': + goto fp_begin; case 'g': case 'G': - if (prec == -1) + if (prec == 0) + prec = 1; +fp_begin: if (prec == -1) prec = DEFPREC; -fp_begin: _double = va_arg(ap, double); + if (flags & LONGDBL) + _double = (double)va_arg(ap, long double); + else + _double = va_arg(ap, double); /* do this before tricky precision changes */ if (isinf(_double)) { if (_double < 0) @@ -728,9 +729,8 @@ number: if ((dprec = prec) >= 0) } else { /* glue together f_p fragments */ if (ch >= 'f') { /* 'f' or 'g' */ if (_double == 0) { - /* kludge for __dtoa irregularity */ - if (prec == 0 || - (flags & ALT) == 0) { + /* kludge for __dtoa irregularity */ + if (prec == 0 && (flags & ALT) == 0) { PRINT("0", 1); } else { PRINT("0.", 2); @@ -799,9 +799,16 @@ cvt(value, ndigits, flags, sign, decpt, ch, length) char *digits, *bp, *rve; if (ch == 'f') - mode = 3; + mode = 3; /* ndigits after the decimal point */ else { - mode = 2; + /* + * To obtain ndigits after the decimal point for the 'e' + * and 'E' formats, round to ndigits + 1 significant + * figures. + */ + if (ch == 'e' || ch == 'E') + ndigits++; + mode = 2; /* ndigits significant digits */ } if (value < 0) { value = -value; @@ -809,7 +816,8 @@ cvt(value, ndigits, flags, sign, decpt, ch, length) } else *sign = '\000'; digits = __dtoa(value, mode, ndigits, decpt, &dsgn, &rve); - if (flags & ALT) { /* Print trailing zeros */ + if ((ch != 'g' && ch != 'G') || flags & ALT) { + /* print trailing zeros */ bp = digits + ndigits; if (ch == 'f') { if (*digits == '0' && value) |