00001
00002
00003
00004
00005
00006 #ifndef NOFLOAT
00007 #include <string.h>
00008 #include <stdarg.h>
00009 #include "../stdio/loc_incl.h"
00010 int _fp_hook = 1;
00011
00012 static char *
00013 _pfloat(long double r, register char *s, int n, int flags)
00014 {
00015 register char *s1;
00016 int sign, dp;
00017 register int i;
00018
00019 s1 = _fcvt(r, n, &dp, &sign);
00020 if (sign)
00021 *s++ = '-';
00022 else if (flags & FL_SIGN)
00023 *s++ = '+';
00024 else if (flags & FL_SPACE)
00025 *s++ = ' ';
00026
00027 if (dp<=0)
00028 *s++ = '0';
00029 for (i=dp; i>0; i--)
00030 if (*s1) *s++ = *s1++;
00031 else *s++ = '0';
00032 if (((i=n) > 0) || (flags & FL_ALT))
00033 *s++ = '.';
00034 while (++dp <= 0) {
00035 if (--i<0)
00036 break;
00037 *s++ = '0';
00038 }
00039 while (--i >= 0)
00040 if (*s1) *s++ = *s1++;
00041 else *s++ = '0';
00042 return s;
00043 }
00044
00045 static char *
00046 _pscien(long double r, register char *s, int n, int flags)
00047 {
00048 int sign, dp;
00049 register char *s1;
00050
00051 s1 = _ecvt(r, n + 1, &dp, &sign);
00052 if (sign)
00053 *s++ = '-';
00054 else if (flags & FL_SIGN)
00055 *s++ = '+';
00056 else if (flags & FL_SPACE)
00057 *s++ = ' ';
00058
00059 *s++ = *s1++;
00060 if ((n > 0) || (flags & FL_ALT))
00061 *s++ = '.';
00062 while (--n >= 0)
00063 if (*s1) *s++ = *s1++;
00064 else *s++ = '0';
00065 *s++ = 'e';
00066 if ( r != 0 ) --dp ;
00067 if ( dp<0 ) {
00068 *s++ = '-' ; dp= -dp ;
00069 } else {
00070 *s++ = '+' ;
00071 }
00072 if (dp >= 100) {
00073 *s++ = '0' + (dp / 100);
00074 dp %= 100;
00075 }
00076 *s++ = '0' + (dp/10);
00077 *s++ = '0' + (dp%10);
00078 return s;
00079 }
00080
00081 #define NDIGINEXP(exp) (((exp) >= 100 || (exp) <= -100) ? 3 : 2)
00082 #define LOW_EXP -4
00083 #define USE_EXP(exp, ndigits) (((exp) < LOW_EXP + 1) || (exp >= ndigits + 1))
00084
00085 static char *
00086 _gcvt(long double value, int ndigit, char *s, int flags)
00087 {
00088 int sign, dp;
00089 register char *s1, *s2;
00090 register int i;
00091 register int nndigit = ndigit;
00092
00093 s1 = _ecvt(value, ndigit, &dp, &sign);
00094 s2 = s;
00095 if (sign) *s2++ = '-';
00096 else if (flags & FL_SIGN)
00097 *s2++ = '+';
00098 else if (flags & FL_SPACE)
00099 *s2++ = ' ';
00100
00101 if (!(flags & FL_ALT))
00102 for (i = nndigit - 1; i > 0 && s1[i] == '0'; i--)
00103 nndigit--;
00104
00105 if (USE_EXP(dp,ndigit)) {
00106
00107 dp--;
00108 *s2++ = *s1++;
00109 if ((nndigit > 1) || (flags & FL_ALT)) *s2++ = '.';
00110 while (--nndigit > 0) *s2++ = *s1++;
00111 *s2++ = 'e';
00112 if (dp < 0) {
00113 *s2++ = '-';
00114 dp = -dp;
00115 }
00116 else *s2++ = '+';
00117 s2 += NDIGINEXP(dp);
00118 *s2 = 0;
00119 for (i = NDIGINEXP(dp); i > 0; i--) {
00120 *--s2 = dp % 10 + '0';
00121 dp /= 10;
00122 }
00123 return s;
00124 }
00125
00126 if (dp <= 0) {
00127 if (*s1 != '0') {
00128
00129 *s2++ = '0';
00130 *s2++ = '.';
00131 }
00132 while (dp < 0) {
00133 dp++;
00134 *s2++ = '0';
00135 }
00136 }
00137 for (i = 1; i <= nndigit; i++) {
00138 *s2++ = *s1++;
00139 if (i == dp) *s2++ = '.';
00140 }
00141 if (i <= dp) {
00142 while (i++ <= dp) *s2++ = '0';
00143 *s2++ = '.';
00144 }
00145 if ((s2[-1]=='.') && !(flags & FL_ALT)) s2--;
00146 *s2 = '\0';
00147 return s;
00148 }
00149
00150 char *
00151 _f_print(va_list *ap, int flags, char *s, char c, int precision)
00152 {
00153 register char *old_s = s;
00154 long double ld_val;
00155
00156 if (flags & FL_LONGDOUBLE) ld_val = va_arg(*ap, long double);
00157 else ld_val = (long double) va_arg(*ap, double);
00158
00159 switch(c) {
00160 case 'f':
00161 s = _pfloat(ld_val, s, precision, flags);
00162 break;
00163 case 'e':
00164 case 'E':
00165 s = _pscien(ld_val, s, precision , flags);
00166 break;
00167 case 'g':
00168 case 'G':
00169 s = _gcvt(ld_val, precision, s, flags);
00170 s += strlen(s);
00171 break;
00172 }
00173 if ( c == 'E' || c == 'G') {
00174 while (*old_s && *old_s != 'e') old_s++;
00175 if (*old_s == 'e') *old_s = 'E';
00176 }
00177 return s;
00178 }
00179 #endif
00180
00181
00182 #include <stdlib.h>
00183 #include "../ansi/ext_fmt.h"
00184
00185 void _str_ext_cvt(const char *s, char **ss, struct EXTEND *e);
00186 double _ext_dbl_cvt(struct EXTEND *e);
00187
00188 double
00189 strtod(const char *p, char **pp)
00190 {
00191 struct EXTEND e;
00192
00193 _str_ext_cvt(p, pp, &e);
00194 return _ext_dbl_cvt(&e);
00195 }