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.
This commit is contained in:
Bruce Evans 1995-03-12 13:26:49 +00:00
parent a28fb64b82
commit d26be6f09d

View File

@ -502,19 +502,20 @@ reswitch: switch (ch) {
base = 10; base = 10;
goto number; goto number;
#ifdef FLOATING_POINT #ifdef FLOATING_POINT
case 'e': /* anomalous precision */ case 'e':
case 'E': case 'E':
prec = (prec == -1) ? case 'f':
DEFPREC + 1 : prec + 1; goto fp_begin;
/* FALLTHROUGH */
case 'f': /* always print trailing zeroes */
if (prec != 0)
flags |= ALT;
case 'g': case 'g':
case 'G': case 'G':
if (prec == -1) if (prec == 0)
prec = 1;
fp_begin: if (prec == -1)
prec = DEFPREC; 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 */ /* do this before tricky precision changes */
if (isinf(_double)) { if (isinf(_double)) {
if (_double < 0) if (_double < 0)
@ -728,9 +729,8 @@ number: if ((dprec = prec) >= 0)
} else { /* glue together f_p fragments */ } else { /* glue together f_p fragments */
if (ch >= 'f') { /* 'f' or 'g' */ if (ch >= 'f') { /* 'f' or 'g' */
if (_double == 0) { if (_double == 0) {
/* kludge for __dtoa irregularity */ /* kludge for __dtoa irregularity */
if (prec == 0 || if (prec == 0 && (flags & ALT) == 0) {
(flags & ALT) == 0) {
PRINT("0", 1); PRINT("0", 1);
} else { } else {
PRINT("0.", 2); PRINT("0.", 2);
@ -799,9 +799,16 @@ cvt(value, ndigits, flags, sign, decpt, ch, length)
char *digits, *bp, *rve; char *digits, *bp, *rve;
if (ch == 'f') if (ch == 'f')
mode = 3; mode = 3; /* ndigits after the decimal point */
else { 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) { if (value < 0) {
value = -value; value = -value;
@ -809,7 +816,8 @@ cvt(value, ndigits, flags, sign, decpt, ch, length)
} else } else
*sign = '\000'; *sign = '\000';
digits = __dtoa(value, mode, ndigits, decpt, &dsgn, &rve); 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; bp = digits + ndigits;
if (ch == 'f') { if (ch == 'f') {
if (*digits == '0' && value) if (*digits == '0' && value)