summaryrefslogtreecommitdiff
path: root/libc/i386fp
diff options
context:
space:
mode:
authorRobert de Bath <rdebath@poboxes.com>2005-01-23 15:31:04 +0100
committerLubomir Rintel <lkundrak@v3.sk>2013-10-23 23:48:50 +0200
commit62c27c1c5cb6257b13dfc9be0394e0d2e86f2735 (patch)
treef702b7e5f80293367e1b6f9812bd45e80378be26 /libc/i386fp
parent6cb598cc5f1c8ae6d14381c2776338584368257e (diff)
downloaddev86-62c27c1c5cb6257b13dfc9be0394e0d2e86f2735.tar.gz
Import Dev86src-0.16.17.tar.gzv0.16.17
Diffstat (limited to 'libc/i386fp')
-rw-r--r--libc/i386fp/Makefile4
-rw-r--r--libc/i386fp/ecvt.c122
2 files changed, 124 insertions, 2 deletions
diff --git a/libc/i386fp/Makefile b/libc/i386fp/Makefile
index 298ca18..e26ce21 100644
--- a/libc/i386fp/Makefile
+++ b/libc/i386fp/Makefile
@@ -9,12 +9,12 @@ FPSRC =fadd.x fcomp.x fdiv.x fmul.x fbsr.x \
fperr.c fperror.x fptoi.x fpushd.x fpulld.x \
fpushi.x fpushf.x fpullf.x frexp.x ftst.x \
gcclib.x \
- fabs.x ldexp.x modf.c \
+ fabs.x ldexp.x ecvt.c \
fperr.h fplib.h
FPOBJ =fadd.o fcomp.o fdiv.o fmul.o fpbsr.o \
fperr.o fperror.o fptoi.o fpushd.o fpulld.o \
fpushi.o fpushf.o fpullf.o frexp.o ftst.o \
- fabs.o ldexp.o modf.o
+ fabs.o ldexp.o ecvt.o
LIB =.
CFLAGS=$(ARCH) $(CCFLAGS) $(DEFS)
diff --git a/libc/i386fp/ecvt.c b/libc/i386fp/ecvt.c
new file mode 100644
index 0000000..6e0cef1
--- /dev/null
+++ b/libc/i386fp/ecvt.c
@@ -0,0 +1,122 @@
+
+#define DIGMAX 30 /* max # of digits in string */
+#define DIGPREC 17 /* max # of significant digits */
+#define ECVT 0
+#define FCVT 1
+static char digstr[DIGMAX + 1 + 1]; /* +1 for end of string */
+
+ /* +1 in case rounding adds */
+ /* another digit */
+static double negtab[] =
+ { 1e-256, 1e-128, 1e-64, 1e-32, 1e-16, 1e-8, 1e-4, 1e-2, 1e-1, 1.0 };
+static double postab[] =
+ { 1e+256, 1e+128, 1e+64, 1e+32, 1e+16, 1e+8, 1e+4, 1e+2, 1e+1 };
+
+static char *_cvt();
+
+/*************************
+ * Convert double val to a string of
+ * decimal digits.
+ * ndig = # of digits in resulting string
+ * Returns:
+ * *pdecpt = position of decimal point from left of first digit
+ * *psign = nonzero if value was negative
+ */
+char *
+ecvt(val, ndig, pdecpt, psign)
+double val;
+int ndig, *pdecpt, *psign;
+
+{
+ return _cvt(ECVT, val, ndig, pdecpt, psign);
+}
+
+char *
+fcvt(val, nfrac, pdecpt, psign)
+double val;
+int nfrac, *pdecpt, *psign;
+
+{
+ return _cvt(FCVT, val, nfrac, pdecpt, psign);
+}
+
+static char *
+_cvt(cnvflag, val, ndig, pdecpt, psign)
+double val;
+int ndig, *pdecpt, *psign;
+
+{
+ int decpt, pow, i;
+ char *p;
+ *psign = (val < 0) ? ((val = -val), 1) : 0;
+ ndig = (ndig < 0) ? 0 : (ndig < DIGMAX) ? ndig : DIGMAX;
+ if (val == 0) {
+ for (p = &digstr[0]; p < &digstr[ndig]; p++)
+ *p = '0';
+ decpt = 0;
+ } else {
+ /* Adjust things so that 1 <= val < 10 */
+ /* in these loops if val == MAXDOUBLE) */
+ decpt = 1;
+ pow = 256;
+ i = 0;
+ while (val < 1) {
+ while (val < negtab[i + 1]) {
+ val /= negtab[i];
+ decpt -= pow;
+ }
+ pow >>= 1;
+ i++;
+ }
+ pow = 256;
+ i = 0;
+ while (val >= 10) {
+ while (val >= postab[i]) {
+ val /= postab[i];
+ decpt += pow;
+ }
+ pow >>= 1;
+ i++;
+ }
+ if (cnvflag == FCVT) {
+ ndig += decpt;
+ ndig = (ndig < 0) ? 0 : (ndig < DIGMAX) ? ndig : DIGMAX;
+ }
+
+ /* Pick off digits 1 by 1 and stuff into digstr[] */
+ /* Do 1 extra digit for rounding purposes */
+ for (p = &digstr[0]; p <= &digstr[ndig]; p++) {
+ int n;
+
+ /* 'twould be silly to have zillions of digits */
+ /* when only DIGPREC are significant */
+ if (p >= &digstr[DIGPREC])
+ *p = '0';
+
+ else {
+ n = val;
+ *p = n + '0';
+ val = (val - n) * 10; /* get next digit */
+ }
+ }
+ if (*--p >= '5') { /* if we need to round */
+ while (1) {
+ if (p == &digstr[0]) { /* if at start */
+ ndig += cnvflag;
+ decpt++; /* shift dec pnt */
+ digstr[0] = '1'; /* "100000..." */
+ break;
+ }
+ *p = '0';
+ --p;
+ if (*p != '9') {
+ (*p)++;
+ break;
+ }
+ } /* while */
+ } /* if */
+ } /* else */
+ *pdecpt = decpt;
+ digstr[ndig] = 0; /* terminate string */
+ return &digstr[0];
+}