summaryrefslogtreecommitdiffstats
path: root/lib/libc/stdio/vfprintf.c
diff options
context:
space:
mode:
authorbde <bde@FreeBSD.org>1995-03-12 13:26:49 +0000
committerbde <bde@FreeBSD.org>1995-03-12 13:26:49 +0000
commit498e010b3a0e93a1ea7e9cf4db9e4736ffb84c5b (patch)
tree36540ff6c0d4d497e5f15d84c999123d84dda984 /lib/libc/stdio/vfprintf.c
parent3fefa68386316c4160eb85a42c3b79b7b89f62a7 (diff)
downloadFreeBSD-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.
Diffstat (limited to 'lib/libc/stdio/vfprintf.c')
-rw-r--r--lib/libc/stdio/vfprintf.c38
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)
OpenPOWER on IntegriCloud