fphook.c

Go to the documentation of this file.
00001 /*
00002  * fltpr.c - print floating point numbers
00003  */
00004 /* $Header: /opt/proj/minix/cvsroot/src/lib/gnu/ieee_float/fphook.c,v 1.1 2005/10/10 15:28:15 beng Exp $ */
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                 /* Use E format */
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         /* Use f format */
00126         if (dp <= 0) {
00127                 if (*s1 != '0') {
00128                         /* otherwise the whole number is 0 */
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  /* NOFLOAT */
00180 /* $Header: /opt/proj/minix/cvsroot/src/lib/gnu/ieee_float/fphook.c,v 1.1 2005/10/10 15:28:15 beng Exp $ */
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 }

Generated on Fri Apr 14 22:57:25 2006 for minix by  doxygen 1.4.6