- p = t;
- }
- /*
- * if no fraction, the number was zero, and if no precision, can't
- * show anything after the decimal point.
- */
- else if (!fract || !prec) {
- *startp++ = '0';
- if (decpt && !(format&GFORMAT))
- *startp++ = '.';
- *startp = '\0';
- return(startp);
- }
- /*
- * if the format is g/G, and the resulting exponent will be less than
- * -4 use e/E format. If e/E format, compute exponent value.
- */
- else if (format&GFORMAT && fract < .0001 || format&EFORMAT) {
- format |= EFORMAT;
- if (fract)
- for (p = startp; fract;) {
- fract = modf(fract * 10, &tmp);
- if (!tmp) {
- --expcnt;
- continue;
+ /* if requires more precision and some fraction left */
+ if (fract) {
+ if (prec)
+ do {
+ fract = modf(fract * 10, &tmp);
+ *t++ = tochar((int)tmp);
+ } while (--prec && fract);
+ if (fract)
+ startp = round(fract, &expcnt, startp,
+ t - 1, (char)0, signp);
+ }
+ /* if requires more precision */
+ for (; prec--; *t++ = '0');
+
+ /* unless alternate flag, trim any g/G format trailing 0's */
+ if (gformat && !(flags&ALT)) {
+ while (t > startp && *--t == '0');
+ if (*t == '.')
+ --t;
+ ++t;
+ }
+ t = exponent(t, expcnt, fmtch);
+ break;
+ case 'g':
+ case 'G':
+ /* a precision of 0 is treated as a precision of 1. */
+ if (!prec)
+ ++prec;
+ /*
+ * ``The style used depends on the value converted; style e
+ * will be used only if the exponent resulting from the
+ * conversion is less than -4 or greater than the precision.''
+ * -- ANSI X3J11
+ */
+ if (expcnt > prec || !expcnt && fract && fract < .0001) {
+ /*
+ * g/G format counts "significant digits, not digits of
+ * precision; for the e/E format, this just causes an
+ * off-by-one problem, i.e. g/G considers the digit
+ * before the decimal point significant and e/E doesn't
+ * count it as precision.
+ */
+ --prec;
+ fmtch -= 2; /* G->E, g->e */
+ gformat = 1;
+ goto eformat;
+ }
+ /*
+ * reverse integer into beginning of buffer,
+ * note, decrement precision
+ */
+ if (expcnt)
+ for (; ++p < endp; *t++ = *p, --prec);
+ else
+ *t++ = '0';
+ /*
+ * if precision required or alternate flag set, add in a
+ * decimal point. If no digits yet, add in leading 0.
+ */
+ if (prec || flags&ALT) {
+ dotrim = 1;
+ *t++ = '.';
+ }
+ else
+ dotrim = 0;
+ /* if requires more precision and some fraction left */
+ if (fract) {
+ if (prec) {
+ do {
+ fract = modf(fract * 10, &tmp);
+ *t++ = tochar((int)tmp);
+ } while(!tmp);
+ while (--prec && fract) {
+ fract = modf(fract * 10, &tmp);
+ *t++ = tochar((int)tmp);