1*0d601874SDavid du Colombier /* 2*0d601874SDavid du Colombier * The authors of this software are Rob Pike and Ken Thompson. 3*0d601874SDavid du Colombier * Copyright (c) 2002 by Lucent Technologies. 4*0d601874SDavid du Colombier * Permission to use, copy, modify, and distribute this software for any 5*0d601874SDavid du Colombier * purpose without fee is hereby granted, provided that this entire notice 6*0d601874SDavid du Colombier * is included in all copies of any software which is or includes a copy 7*0d601874SDavid du Colombier * or modification of this software and in all copies of the supporting 8*0d601874SDavid du Colombier * documentation for such software. 9*0d601874SDavid du Colombier * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED 10*0d601874SDavid du Colombier * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE 11*0d601874SDavid du Colombier * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY 12*0d601874SDavid du Colombier * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. 13*0d601874SDavid du Colombier */ 148ccd4a63SDavid du Colombier #include <u.h> 158ccd4a63SDavid du Colombier #include <libc.h> 16*0d601874SDavid du Colombier #include <float.h> 178ccd4a63SDavid du Colombier #include <ctype.h> 188ccd4a63SDavid du Colombier #include "fmtdef.h" 198ccd4a63SDavid du Colombier 208ccd4a63SDavid du Colombier enum 218ccd4a63SDavid du Colombier { 228ccd4a63SDavid du Colombier FDIGIT = 30, 238ccd4a63SDavid du Colombier FDEFLT = 6, 24*0d601874SDavid du Colombier NSIGNIF = 17 258ccd4a63SDavid du Colombier }; 268ccd4a63SDavid du Colombier 27*0d601874SDavid du Colombier /* 28*0d601874SDavid du Colombier * first few powers of 10, enough for about 1/2 of the 29*0d601874SDavid du Colombier * total space for doubles. 30*0d601874SDavid du Colombier */ 31*0d601874SDavid du Colombier static double pows10[] = 32*0d601874SDavid du Colombier { 33*0d601874SDavid du Colombier 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 34*0d601874SDavid du Colombier 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 35*0d601874SDavid du Colombier 1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29, 36*0d601874SDavid du Colombier 1e30, 1e31, 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39, 37*0d601874SDavid du Colombier 1e40, 1e41, 1e42, 1e43, 1e44, 1e45, 1e46, 1e47, 1e48, 1e49, 38*0d601874SDavid du Colombier 1e50, 1e51, 1e52, 1e53, 1e54, 1e55, 1e56, 1e57, 1e58, 1e59, 39*0d601874SDavid du Colombier 1e60, 1e61, 1e62, 1e63, 1e64, 1e65, 1e66, 1e67, 1e68, 1e69, 40*0d601874SDavid du Colombier 1e70, 1e71, 1e72, 1e73, 1e74, 1e75, 1e76, 1e77, 1e78, 1e79, 41*0d601874SDavid du Colombier 1e80, 1e81, 1e82, 1e83, 1e84, 1e85, 1e86, 1e87, 1e88, 1e89, 42*0d601874SDavid du Colombier 1e90, 1e91, 1e92, 1e93, 1e94, 1e95, 1e96, 1e97, 1e98, 1e99, 43*0d601874SDavid du Colombier 1e100, 1e101, 1e102, 1e103, 1e104, 1e105, 1e106, 1e107, 1e108, 1e109, 44*0d601874SDavid du Colombier 1e110, 1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119, 45*0d601874SDavid du Colombier 1e120, 1e121, 1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129, 46*0d601874SDavid du Colombier 1e130, 1e131, 1e132, 1e133, 1e134, 1e135, 1e136, 1e137, 1e138, 1e139, 47*0d601874SDavid du Colombier 1e140, 1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149, 48*0d601874SDavid du Colombier 1e150, 1e151, 1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159, 49*0d601874SDavid du Colombier }; 50*0d601874SDavid du Colombier 51*0d601874SDavid du Colombier #undef pow10 52*0d601874SDavid du Colombier #define pow10(x) fmtpow10(x) 53*0d601874SDavid du Colombier 54*0d601874SDavid du Colombier static double 55*0d601874SDavid du Colombier pow10(int n) 56*0d601874SDavid du Colombier { 57*0d601874SDavid du Colombier double d; 58*0d601874SDavid du Colombier int neg; 59*0d601874SDavid du Colombier 60*0d601874SDavid du Colombier neg = 0; 61*0d601874SDavid du Colombier if(n < 0){ 62*0d601874SDavid du Colombier if(n < DBL_MIN_10_EXP){ 63*0d601874SDavid du Colombier return 0.; 64*0d601874SDavid du Colombier } 65*0d601874SDavid du Colombier neg = 1; 66*0d601874SDavid du Colombier n = -n; 67*0d601874SDavid du Colombier }else if(n > DBL_MAX_10_EXP){ 68*0d601874SDavid du Colombier return HUGE_VAL; 69*0d601874SDavid du Colombier } 70*0d601874SDavid du Colombier if(n < (int)(sizeof(pows10)/sizeof(pows10[0]))) 71*0d601874SDavid du Colombier d = pows10[n]; 72*0d601874SDavid du Colombier else{ 73*0d601874SDavid du Colombier d = pows10[sizeof(pows10)/sizeof(pows10[0]) - 1]; 74*0d601874SDavid du Colombier for(;;){ 75*0d601874SDavid du Colombier n -= sizeof(pows10)/sizeof(pows10[0]) - 1; 76*0d601874SDavid du Colombier if(n < (int)(sizeof(pows10)/sizeof(pows10[0]))){ 77*0d601874SDavid du Colombier d *= pows10[n]; 78*0d601874SDavid du Colombier break; 79*0d601874SDavid du Colombier } 80*0d601874SDavid du Colombier d *= pows10[sizeof(pows10)/sizeof(pows10[0]) - 1]; 81*0d601874SDavid du Colombier } 82*0d601874SDavid du Colombier } 83*0d601874SDavid du Colombier if(neg){ 84*0d601874SDavid du Colombier return 1./d; 85*0d601874SDavid du Colombier } 86*0d601874SDavid du Colombier return d; 87*0d601874SDavid du Colombier } 88*0d601874SDavid du Colombier 898ccd4a63SDavid du Colombier static int 908ccd4a63SDavid du Colombier xadd(char *a, int n, int v) 918ccd4a63SDavid du Colombier { 928ccd4a63SDavid du Colombier char *b; 938ccd4a63SDavid du Colombier int c; 948ccd4a63SDavid du Colombier 958ccd4a63SDavid du Colombier if(n < 0 || n >= NSIGNIF) 968ccd4a63SDavid du Colombier return 0; 978ccd4a63SDavid du Colombier for(b = a+n; b >= a; b--) { 988ccd4a63SDavid du Colombier c = *b + v; 998ccd4a63SDavid du Colombier if(c <= '9') { 1008ccd4a63SDavid du Colombier *b = c; 1018ccd4a63SDavid du Colombier return 0; 1028ccd4a63SDavid du Colombier } 1038ccd4a63SDavid du Colombier *b = '0'; 1048ccd4a63SDavid du Colombier v = 1; 1058ccd4a63SDavid du Colombier } 106*0d601874SDavid du Colombier *a = '1'; /* overflow adding */ 1078ccd4a63SDavid du Colombier return 1; 1088ccd4a63SDavid du Colombier } 1098ccd4a63SDavid du Colombier 1108ccd4a63SDavid du Colombier static int 1118ccd4a63SDavid du Colombier xsub(char *a, int n, int v) 1128ccd4a63SDavid du Colombier { 1138ccd4a63SDavid du Colombier char *b; 1148ccd4a63SDavid du Colombier int c; 1158ccd4a63SDavid du Colombier 1168ccd4a63SDavid du Colombier for(b = a+n; b >= a; b--) { 1178ccd4a63SDavid du Colombier c = *b - v; 1188ccd4a63SDavid du Colombier if(c >= '0') { 1198ccd4a63SDavid du Colombier *b = c; 1208ccd4a63SDavid du Colombier return 0; 1218ccd4a63SDavid du Colombier } 1228ccd4a63SDavid du Colombier *b = '9'; 1238ccd4a63SDavid du Colombier v = 1; 1248ccd4a63SDavid du Colombier } 125*0d601874SDavid du Colombier *a = '9'; /* underflow subtracting */ 1268ccd4a63SDavid du Colombier return 1; 1278ccd4a63SDavid du Colombier } 1288ccd4a63SDavid du Colombier 1298ccd4a63SDavid du Colombier static void 1308ccd4a63SDavid du Colombier xdtoa(Fmt *fmt, char *s2, double f) 1318ccd4a63SDavid du Colombier { 1328ccd4a63SDavid du Colombier char s1[NSIGNIF+10]; 1338ccd4a63SDavid du Colombier double g, h; 1348ccd4a63SDavid du Colombier int e, d, i, n; 1358ccd4a63SDavid du Colombier int c1, c2, c3, c4, ucase, sign, chr, prec; 1368ccd4a63SDavid du Colombier 1378ccd4a63SDavid du Colombier prec = FDEFLT; 1388ccd4a63SDavid du Colombier if(fmt->flags & FmtPrec) 1398ccd4a63SDavid du Colombier prec = fmt->prec; 1408ccd4a63SDavid du Colombier if(prec > FDIGIT) 1418ccd4a63SDavid du Colombier prec = FDIGIT; 1428ccd4a63SDavid du Colombier if(__isNaN(f)) { 1438ccd4a63SDavid du Colombier strcpy(s2, "NaN"); 1448ccd4a63SDavid du Colombier return; 1458ccd4a63SDavid du Colombier } 1468ccd4a63SDavid du Colombier if(__isInf(f, 1)) { 1478ccd4a63SDavid du Colombier strcpy(s2, "+Inf"); 1488ccd4a63SDavid du Colombier return; 1498ccd4a63SDavid du Colombier } 1508ccd4a63SDavid du Colombier if(__isInf(f, -1)) { 1518ccd4a63SDavid du Colombier strcpy(s2, "-Inf"); 1528ccd4a63SDavid du Colombier return; 1538ccd4a63SDavid du Colombier } 1548ccd4a63SDavid du Colombier sign = 0; 1558ccd4a63SDavid du Colombier if(f < 0) { 1568ccd4a63SDavid du Colombier f = -f; 1578ccd4a63SDavid du Colombier sign++; 1588ccd4a63SDavid du Colombier } 1598ccd4a63SDavid du Colombier ucase = 0; 1608ccd4a63SDavid du Colombier chr = fmt->r; 1618ccd4a63SDavid du Colombier if(isupper(chr)) { 1628ccd4a63SDavid du Colombier ucase = 1; 1638ccd4a63SDavid du Colombier chr = tolower(chr); 1648ccd4a63SDavid du Colombier } 1658ccd4a63SDavid du Colombier 1668ccd4a63SDavid du Colombier e = 0; 1678ccd4a63SDavid du Colombier g = f; 1688ccd4a63SDavid du Colombier if(g != 0) { 1698ccd4a63SDavid du Colombier frexp(f, &e); 1708ccd4a63SDavid du Colombier e = e * .301029995664; 1718ccd4a63SDavid du Colombier if(e >= -150 && e <= +150) { 1728ccd4a63SDavid du Colombier d = 0; 1738ccd4a63SDavid du Colombier h = f; 1748ccd4a63SDavid du Colombier } else { 1758ccd4a63SDavid du Colombier d = e/2; 1768ccd4a63SDavid du Colombier h = f * pow10(-d); 1778ccd4a63SDavid du Colombier } 1788ccd4a63SDavid du Colombier g = h * pow10(d-e); 1798ccd4a63SDavid du Colombier while(g < 1) { 1808ccd4a63SDavid du Colombier e--; 1818ccd4a63SDavid du Colombier g = h * pow10(d-e); 1828ccd4a63SDavid du Colombier } 1838ccd4a63SDavid du Colombier while(g >= 10) { 1848ccd4a63SDavid du Colombier e++; 1858ccd4a63SDavid du Colombier g = h * pow10(d-e); 1868ccd4a63SDavid du Colombier } 1878ccd4a63SDavid du Colombier } 1888ccd4a63SDavid du Colombier 1898ccd4a63SDavid du Colombier /* 1908ccd4a63SDavid du Colombier * convert NSIGNIF digits and convert 1918ccd4a63SDavid du Colombier * back to get accuracy. 1928ccd4a63SDavid du Colombier */ 1938ccd4a63SDavid du Colombier for(i=0; i<NSIGNIF; i++) { 1948ccd4a63SDavid du Colombier d = g; 1958ccd4a63SDavid du Colombier s1[i] = d + '0'; 1968ccd4a63SDavid du Colombier g = (g - d) * 10; 1978ccd4a63SDavid du Colombier } 1988ccd4a63SDavid du Colombier s1[i] = 0; 1998ccd4a63SDavid du Colombier 2008ccd4a63SDavid du Colombier /* 2018ccd4a63SDavid du Colombier * try decimal rounding to eliminate 9s 2028ccd4a63SDavid du Colombier */ 2038ccd4a63SDavid du Colombier c2 = prec + 1; 2048ccd4a63SDavid du Colombier if(chr == 'f') 2058ccd4a63SDavid du Colombier c2 += e; 2068ccd4a63SDavid du Colombier if(c2 >= NSIGNIF-2) { 2078ccd4a63SDavid du Colombier strcpy(s2, s1); 2088ccd4a63SDavid du Colombier d = e; 2098ccd4a63SDavid du Colombier s1[NSIGNIF-2] = '0'; 2108ccd4a63SDavid du Colombier s1[NSIGNIF-1] = '0'; 2118ccd4a63SDavid du Colombier sprint(s1+NSIGNIF, "e%d", e-NSIGNIF+1); 2128ccd4a63SDavid du Colombier g = strtod(s1, nil); 2138ccd4a63SDavid du Colombier if(g == f) 2148ccd4a63SDavid du Colombier goto found; 2158ccd4a63SDavid du Colombier if(xadd(s1, NSIGNIF-3, 1)) { 2168ccd4a63SDavid du Colombier e++; 2178ccd4a63SDavid du Colombier sprint(s1+NSIGNIF, "e%d", e-NSIGNIF+1); 2188ccd4a63SDavid du Colombier } 2198ccd4a63SDavid du Colombier g = strtod(s1, nil); 2208ccd4a63SDavid du Colombier if(g == f) 2218ccd4a63SDavid du Colombier goto found; 2228ccd4a63SDavid du Colombier strcpy(s1, s2); 2238ccd4a63SDavid du Colombier e = d; 2248ccd4a63SDavid du Colombier } 2258ccd4a63SDavid du Colombier 2268ccd4a63SDavid du Colombier /* 2278ccd4a63SDavid du Colombier * convert back so s1 gets exact answer 2288ccd4a63SDavid du Colombier */ 2298ccd4a63SDavid du Colombier for(;;) { 2308ccd4a63SDavid du Colombier sprint(s1+NSIGNIF, "e%d", e-NSIGNIF+1); 2318ccd4a63SDavid du Colombier g = strtod(s1, nil); 2328ccd4a63SDavid du Colombier if(f > g) { 2338ccd4a63SDavid du Colombier if(xadd(s1, NSIGNIF-1, 1)) 2348ccd4a63SDavid du Colombier e--; 2358ccd4a63SDavid du Colombier continue; 2368ccd4a63SDavid du Colombier } 2378ccd4a63SDavid du Colombier if(f < g) { 2388ccd4a63SDavid du Colombier if(xsub(s1, NSIGNIF-1, 1)) 2398ccd4a63SDavid du Colombier e++; 2408ccd4a63SDavid du Colombier continue; 2418ccd4a63SDavid du Colombier } 2428ccd4a63SDavid du Colombier break; 2438ccd4a63SDavid du Colombier } 2448ccd4a63SDavid du Colombier 2458ccd4a63SDavid du Colombier found: 2468ccd4a63SDavid du Colombier /* 2478ccd4a63SDavid du Colombier * sign 2488ccd4a63SDavid du Colombier */ 2498ccd4a63SDavid du Colombier d = 0; 2508ccd4a63SDavid du Colombier i = 0; 2518ccd4a63SDavid du Colombier if(sign) 2528ccd4a63SDavid du Colombier s2[d++] = '-'; 2538ccd4a63SDavid du Colombier else if(fmt->flags & FmtSign) 2548ccd4a63SDavid du Colombier s2[d++] = '+'; 2558ccd4a63SDavid du Colombier else if(fmt->flags & FmtSpace) 2568ccd4a63SDavid du Colombier s2[d++] = ' '; 2578ccd4a63SDavid du Colombier 2588ccd4a63SDavid du Colombier /* 2598ccd4a63SDavid du Colombier * copy into final place 2608ccd4a63SDavid du Colombier * c1 digits of leading '0' 2618ccd4a63SDavid du Colombier * c2 digits from conversion 2628ccd4a63SDavid du Colombier * c3 digits of trailing '0' 2638ccd4a63SDavid du Colombier * c4 digits after '.' 2648ccd4a63SDavid du Colombier */ 2658ccd4a63SDavid du Colombier c1 = 0; 2668ccd4a63SDavid du Colombier c2 = prec + 1; 2678ccd4a63SDavid du Colombier c3 = 0; 2688ccd4a63SDavid du Colombier c4 = prec; 2698ccd4a63SDavid du Colombier switch(chr) { 2708ccd4a63SDavid du Colombier default: 2718ccd4a63SDavid du Colombier if(xadd(s1, c2, 5)) 2728ccd4a63SDavid du Colombier e++; 2738ccd4a63SDavid du Colombier break; 2748ccd4a63SDavid du Colombier case 'g': 2758ccd4a63SDavid du Colombier /* 2768ccd4a63SDavid du Colombier * decide on 'e' of 'f' style convers 2778ccd4a63SDavid du Colombier */ 2788ccd4a63SDavid du Colombier if(xadd(s1, c2, 5)) 2798ccd4a63SDavid du Colombier e++; 2808ccd4a63SDavid du Colombier if(e >= -5 && e <= prec) { 2818ccd4a63SDavid du Colombier c1 = -e - 1; 2828ccd4a63SDavid du Colombier c4 = prec - e; 2838ccd4a63SDavid du Colombier chr = 'h'; // flag for 'f' style 2848ccd4a63SDavid du Colombier } 2858ccd4a63SDavid du Colombier break; 2868ccd4a63SDavid du Colombier case 'f': 2878ccd4a63SDavid du Colombier if(xadd(s1, c2+e, 5)) 2888ccd4a63SDavid du Colombier e++; 2898ccd4a63SDavid du Colombier c1 = -e; 2908ccd4a63SDavid du Colombier if(c1 > prec) 2918ccd4a63SDavid du Colombier c1 = c2; 2928ccd4a63SDavid du Colombier c2 += e; 2938ccd4a63SDavid du Colombier break; 2948ccd4a63SDavid du Colombier } 2958ccd4a63SDavid du Colombier 2968ccd4a63SDavid du Colombier /* 2978ccd4a63SDavid du Colombier * clean up c1 c2 and c3 2988ccd4a63SDavid du Colombier */ 2998ccd4a63SDavid du Colombier if(c1 < 0) 3008ccd4a63SDavid du Colombier c1 = 0; 3018ccd4a63SDavid du Colombier if(c2 < 0) 3028ccd4a63SDavid du Colombier c2 = 0; 3038ccd4a63SDavid du Colombier if(c2 > NSIGNIF) { 3048ccd4a63SDavid du Colombier c3 = c2-NSIGNIF; 3058ccd4a63SDavid du Colombier c2 = NSIGNIF; 3068ccd4a63SDavid du Colombier } 3078ccd4a63SDavid du Colombier 3088ccd4a63SDavid du Colombier /* 3098ccd4a63SDavid du Colombier * copy digits 3108ccd4a63SDavid du Colombier */ 3118ccd4a63SDavid du Colombier while(c1 > 0) { 3128ccd4a63SDavid du Colombier if(c1+c2+c3 == c4) 3138ccd4a63SDavid du Colombier s2[d++] = '.'; 3148ccd4a63SDavid du Colombier s2[d++] = '0'; 3158ccd4a63SDavid du Colombier c1--; 3168ccd4a63SDavid du Colombier } 3178ccd4a63SDavid du Colombier while(c2 > 0) { 3188ccd4a63SDavid du Colombier if(c2+c3 == c4) 3198ccd4a63SDavid du Colombier s2[d++] = '.'; 3208ccd4a63SDavid du Colombier s2[d++] = s1[i++]; 3218ccd4a63SDavid du Colombier c2--; 3228ccd4a63SDavid du Colombier } 3238ccd4a63SDavid du Colombier while(c3 > 0) { 3248ccd4a63SDavid du Colombier if(c3 == c4) 3258ccd4a63SDavid du Colombier s2[d++] = '.'; 3268ccd4a63SDavid du Colombier s2[d++] = '0'; 3278ccd4a63SDavid du Colombier c3--; 3288ccd4a63SDavid du Colombier } 3298ccd4a63SDavid du Colombier 3308ccd4a63SDavid du Colombier /* 3318ccd4a63SDavid du Colombier * strip trailing '0' on g conv 3328ccd4a63SDavid du Colombier */ 3338ccd4a63SDavid du Colombier if(fmt->flags & FmtSharp) { 3348ccd4a63SDavid du Colombier if(0 == c4) 3358ccd4a63SDavid du Colombier s2[d++] = '.'; 3368ccd4a63SDavid du Colombier } else 3378ccd4a63SDavid du Colombier if(chr == 'g' || chr == 'h') { 3388ccd4a63SDavid du Colombier for(n=d-1; n>=0; n--) 3398ccd4a63SDavid du Colombier if(s2[n] != '0') 3408ccd4a63SDavid du Colombier break; 3418ccd4a63SDavid du Colombier for(i=n; i>=0; i--) 3428ccd4a63SDavid du Colombier if(s2[i] == '.') { 3438ccd4a63SDavid du Colombier d = n; 3448ccd4a63SDavid du Colombier if(i != n) 3458ccd4a63SDavid du Colombier d++; 3468ccd4a63SDavid du Colombier break; 3478ccd4a63SDavid du Colombier } 3488ccd4a63SDavid du Colombier } 3498ccd4a63SDavid du Colombier if(chr == 'e' || chr == 'g') { 3508ccd4a63SDavid du Colombier if(ucase) 3518ccd4a63SDavid du Colombier s2[d++] = 'E'; 3528ccd4a63SDavid du Colombier else 3538ccd4a63SDavid du Colombier s2[d++] = 'e'; 3548ccd4a63SDavid du Colombier c1 = e; 3558ccd4a63SDavid du Colombier if(c1 < 0) { 3568ccd4a63SDavid du Colombier s2[d++] = '-'; 3578ccd4a63SDavid du Colombier c1 = -c1; 3588ccd4a63SDavid du Colombier } else 3598ccd4a63SDavid du Colombier s2[d++] = '+'; 3608ccd4a63SDavid du Colombier if(c1 >= 100) { 3618ccd4a63SDavid du Colombier s2[d++] = c1/100 + '0'; 3628ccd4a63SDavid du Colombier c1 = c1%100; 3638ccd4a63SDavid du Colombier } 3648ccd4a63SDavid du Colombier s2[d++] = c1/10 + '0'; 3658ccd4a63SDavid du Colombier s2[d++] = c1%10 + '0'; 3668ccd4a63SDavid du Colombier } 3678ccd4a63SDavid du Colombier s2[d] = 0; 3688ccd4a63SDavid du Colombier } 3698ccd4a63SDavid du Colombier 370*0d601874SDavid du Colombier static int 371*0d601874SDavid du Colombier floatfmt(Fmt *fmt, double f) 3728ccd4a63SDavid du Colombier { 373*0d601874SDavid du Colombier char s[341]; /* precision+exponent+sign+'.'+null */ 3748ccd4a63SDavid du Colombier 3758ccd4a63SDavid du Colombier xdtoa(fmt, s, f); 3768ccd4a63SDavid du Colombier fmt->flags &= FmtWidth|FmtLeft; 377*0d601874SDavid du Colombier __fmtcpy(fmt, s, strlen(s), strlen(s)); 3788ccd4a63SDavid du Colombier return 0; 3798ccd4a63SDavid du Colombier } 3808ccd4a63SDavid du Colombier 3818ccd4a63SDavid du Colombier int 382*0d601874SDavid du Colombier __efgfmt(Fmt *f) 3838ccd4a63SDavid du Colombier { 3848ccd4a63SDavid du Colombier double d; 3858ccd4a63SDavid du Colombier 3868ccd4a63SDavid du Colombier d = va_arg(f->args, double); 387*0d601874SDavid du Colombier return floatfmt(f, d); 3888ccd4a63SDavid du Colombier } 389