15 xadd(char *a, int n, int v)
20 if(n < 0 || n >= NSIGNIF)
22 for(b = a+n; b >= a; b--) {
31 *a = '1'; // overflow adding
36 xsub(char *a, int n, int v)
41 for(b = a+n; b >= a; b--) {
50 *a = '9'; // underflow subtracting
55 xdtoa(Fmt *fmt, char *s2, double f)
60 int c1, c2, c3, c4, ucase, sign, chr, prec;
63 if(fmt->flags & FmtPrec)
95 e = e * .301029995664;
96 if(e >= -150 && e <= +150) {
115 * convert NSIGNIF digits and convert
116 * back to get accuracy.
118 for(i=0; i<NSIGNIF; i++) {
126 * try decimal rounding to eliminate 9s
131 if(c2 >= NSIGNIF-2) {
136 sprint(s1+NSIGNIF, "e%d", e-NSIGNIF+1);
140 if(xadd(s1, NSIGNIF-3, 1)) {
142 sprint(s1+NSIGNIF, "e%d", e-NSIGNIF+1);
152 * convert back so s1 gets exact answer
155 sprint(s1+NSIGNIF, "e%d", e-NSIGNIF+1);
158 if(xadd(s1, NSIGNIF-1, 1))
163 if(xsub(s1, NSIGNIF-1, 1))
178 else if(fmt->flags & FmtSign)
180 else if(fmt->flags & FmtSpace)
184 * copy into final place
185 * c1 digits of leading '0'
186 * c2 digits from conversion
187 * c3 digits of trailing '0'
188 * c4 digits after '.'
190 if(chr == 'g' && prec > 0) /* Significant figures. */
203 * decide on 'e' of 'f' style convers
207 if(e >= -4 && e <= prec) {
210 chr = 'h'; // flag for 'f' style
214 if(xadd(s1, c2+e, 5))
224 * clean up c1 c2 and c3
258 * strip trailing '0' on g conv
260 if(fmt->flags & FmtSharp) {
264 if(chr == 'g' || chr == 'h') {
265 for(n=d-1; n>=0; n--)
276 if(chr == 'e' || chr == 'g') {
288 s2[d++] = c1/100 + '0';
291 s2[d++] = c1/10 + '0';
292 s2[d++] = c1%10 + '0';
298 _floatfmt(Fmt *fmt, double f)
300 char s[1+NEXP10+1+FDIGIT+1];
303 * The max length of a %f string is
304 * '[+-]'+"max exponent"+'.'+"max precision"+'\0'
305 * which is 341 currently.
308 fmt->flags &= FmtWidth|FmtLeft;
309 _fmtcpy(fmt, s, strlen(s), strlen(s));
318 d = va_arg(f->args, double);
319 return _floatfmt(f, d);