cvt.c

Go to the documentation of this file.
00001 /* $Header: /opt/proj/minix/cvsroot/src/lib/ack/libp/cvt.c,v 1.1 2005/10/10 15:27:46 beng Exp $ */
00002 #ifndef NOFLOAT
00003 
00004 #if __STDC__
00005 #include <float.h>
00006 #else
00007 #include <math.h>
00008 #define DBL_MAX M_MAX_D
00009 #endif
00010 
00011 static char *cvt();
00012 #define NDIGITS 128
00013 
00014 char *
00015 _ecvt(value, ndigit, decpt, sign)
00016         double value;
00017         int ndigit, *decpt, *sign;
00018 {
00019         return cvt(value, ndigit, decpt, sign, 1);
00020 }
00021 
00022 char *
00023 _fcvt(value, ndigit, decpt, sign)
00024         double value;
00025         int ndigit, *decpt, *sign;
00026 {
00027         return cvt(value, ndigit, decpt, sign, 0);
00028 }
00029 
00030 static struct powers_of_10 {
00031         double pval;
00032         double rpval;
00033         int exp;
00034 } p10[] = {
00035         1.0e32, 1.0e-32, 32,
00036         1.0e16, 1.0e-16, 16,
00037         1.0e8, 1.0e-8, 8,
00038         1.0e4, 1.0e-4, 4,
00039         1.0e2, 1.0e-2, 2,
00040         1.0e1, 1.0e-1, 1,
00041         1.0e0, 1.0e0, 0
00042 };
00043 
00044 static char *
00045 cvt(value, ndigit, decpt, sign, ecvtflag)
00046         double value;
00047         int ndigit, *decpt, *sign;
00048 {
00049         static char buf[NDIGITS+1];
00050         register char *p = buf;
00051         register char *pe;
00052 
00053         if (ndigit < 0) ndigit = 0;
00054         if (ndigit > NDIGITS) ndigit = NDIGITS;
00055         pe = &buf[ndigit];
00056         buf[0] = '\0';
00057 
00058         *sign = 0;
00059         if (value < 0) {
00060                 *sign = 1;
00061                 value = -value;
00062         }
00063 
00064         *decpt = 0;
00065         if (value >= DBL_MAX) {
00066                 value = DBL_MAX;
00067         }
00068         if (value != 0.0) {
00069                 register struct powers_of_10 *pp = &p10[0];
00070 
00071                 if (value >= 10.0) do {
00072                         while (value >= pp->pval) {
00073                                 value *= pp->rpval;
00074                                 *decpt += pp->exp;
00075                         }
00076                 } while ((++pp)->exp > 0);
00077 
00078                 pp = &p10[0];
00079                 if (value < 1.0) do {
00080                         while (value * pp->pval < 10.0) {
00081                                 value *= pp->pval;
00082                                 *decpt -= pp->exp;
00083                         }
00084                 } while ((++pp)->exp > 0);
00085 
00086                 (*decpt)++;     /* because now value in [1.0, 10.0) */
00087         }
00088         if (! ecvtflag) {
00089                 /* for fcvt() we need ndigit digits behind the dot */
00090                 pe += *decpt;
00091                 if (pe > &buf[NDIGITS]) pe = &buf[NDIGITS];
00092         }
00093         while (p <= pe) {
00094                 *p++ = (int)value + '0';
00095                 value = 10.0 * (value - (int)value);
00096         }
00097         if (pe >= buf) {
00098                 p = pe;
00099                 *p += 5;        /* round of at the end */
00100                 while (*p > '9') {
00101                         *p = '0';
00102                         if (p > buf) ++*--p;
00103                         else {
00104                                 *p = '1';
00105                                 ++*decpt;
00106                                 if (! ecvtflag) {
00107                                         /* maybe add another digit at the end,
00108                                            because the point was shifted right
00109                                         */
00110                                         if (pe > buf) *pe = '0';
00111                                         pe++;
00112                                 }
00113                         }
00114                 }
00115                 *pe = '\0';
00116         }
00117         return buf;
00118 }
00119 #endif

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