Some modifications to improve floating point printing

This commit is contained in:
ceriel 1991-02-26 18:37:47 +00:00
parent d50d1f6c5e
commit cb7438cb99

View file

@ -538,7 +538,18 @@ _str_ext_cvt(const char *s, char **ss, struct EXTEND *e)
#include <math.h> #include <math.h>
static
ten_mult(struct EXTEND *e)
{
struct EXTEND e1 = *e;
e1.exp++;
e->exp += 3;
add_ext(e, &e1, e);
}
#define NDIGITS 128 #define NDIGITS 128
#define NSIGNIFICANT 19
char * char *
_ext_str_cvt(struct EXTEND *e, int ndigit, int *decpt, int *sign, int ecvtflag) _ext_str_cvt(struct EXTEND *e, int ndigit, int *decpt, int *sign, int ecvtflag)
@ -546,6 +557,7 @@ _ext_str_cvt(struct EXTEND *e, int ndigit, int *decpt, int *sign, int ecvtflag)
/* Like cvt(), but for extended precision */ /* Like cvt(), but for extended precision */
static char buf[NDIGITS+1]; static char buf[NDIGITS+1];
struct EXTEND m;
register char *p = buf; register char *p = buf;
register char *pe; register char *pe;
int findex = 0; int findex = 0;
@ -584,7 +596,7 @@ _ext_str_cvt(struct EXTEND *e, int ndigit, int *decpt, int *sign, int ecvtflag)
mul_ext(e, &big_ten_powers[findex], e); mul_ext(e, &big_ten_powers[findex], e);
*decpt -= findex * TP; *decpt -= findex * TP;
/* here, value >= 10 ** -28 */ /* here, value >= 10 ** -28 */
mul_ext(e, &ten_powers[1], e); ten_mult(e);
(*decpt)--; (*decpt)--;
pp = &r_ten_powers[0]; pp = &r_ten_powers[0];
while(cmp_ext(e, pp) < 0) pp++; while(cmp_ext(e, pp) < 0) pp++;
@ -600,7 +612,17 @@ _ext_str_cvt(struct EXTEND *e, int ndigit, int *decpt, int *sign, int ecvtflag)
pe += *decpt; pe += *decpt;
if (pe > &buf[NDIGITS]) pe = &buf[NDIGITS]; if (pe > &buf[NDIGITS]) pe = &buf[NDIGITS];
} }
m.exp = -62;
m.sign = 0;
m.m1 = 0xA0000000;
m.m2 = 0;
while (p <= pe) { while (p <= pe) {
struct EXTEND oneminm;
if (p - pe > NSIGNIFICANT) {
findex = 0;
e->m1 = 0;
}
if (findex) { if (findex) {
struct EXTEND tc, oldtc; struct EXTEND tc, oldtc;
int count = 0; int count = 0;
@ -621,20 +643,31 @@ _ext_str_cvt(struct EXTEND *e, int ndigit, int *decpt, int *sign, int ecvtflag)
findex--; findex--;
continue; continue;
} }
if (e->exp >= 0 && e->m1 != 0) { if (e->m1) {
struct EXTEND x; m.sign = 1;
add_ext(&ten_powers[0], &m, &oneminm);
m.sign = 0;
if (e->exp >= 0) {
struct EXTEND x;
x.m2 = 0; x.exp = e->exp; x.m2 = 0; x.exp = e->exp;
x.sign = 1; x.sign = 1;
x.m1 = e->m1>>(31-e->exp); x.m1 = e->m1>>(31-e->exp);
*p++ = (x.m1) + '0'; *p++ = (x.m1) + '0';
if (x.m1) {
x.m1 = x.m1 << (31-e->exp); x.m1 = x.m1 << (31-e->exp);
add_ext(e, &x, e); add_ext(e, &x, e);
} }
else *p++ = '0';
/* Check that remainder is still significant */
if (cmp_ext(&m, e) > 0 || cmp_ext(e, &oneminm) > 0) {
e->m1 = 0;
if (e->exp >= -1) *(p-1) += 1;
continue;
}
ten_mult(&m);
ten_mult(e);
} }
else *p++ = '0'; else *p++ = '0';
if (e->m1) mul_ext(e, &ten_powers[1], e);
} }
if (pe >= buf) { if (pe >= buf) {
p = pe; p = pe;
@ -670,18 +703,11 @@ _dbl_ext_cvt(double value, struct EXTEND *e)
e->sign = value < 0.0; e->sign = value < 0.0;
if (e->sign) value = -value; if (e->sign) value = -value;
e->exp = exponent - 1; e->exp = exponent - 1;
e->m1 = 0; value *= 4294967296.0;
e->m2 = 0; e->m1 = value;
for (i = 64; i > 0 && value != 0; i--) { value -= e->m1;
double ipart; value *= 4294967296.0;
e->m2 = value;
b64_sft(&(e->mantissa),-1);
value = modf(2.0*value, &ipart);
if (ipart) {
e->m2 |= 1;
}
}
if (i > 0) b64_sft(&(e->mantissa),-i);
} }
static struct EXTEND max_d; static struct EXTEND max_d;
@ -705,7 +731,7 @@ _ext_dbl_cvt(struct EXTEND *e)
f = HUGE_VAL; f = HUGE_VAL;
errno = ERANGE; errno = ERANGE;
} }
else f = ldexp(ldexp((double)e->m1, 32) + (double)e->m2, e->exp-63); else f = ldexp((double)e->m1*4294967296.0 + (double)e->m2, e->exp-63);
if (sign) f = -f; if (sign) f = -f;
if (f == 0.0 && (e->m1 != 0 || e->m2 != 0)) { if (f == 0.0 && (e->m1 != 0 || e->m2 != 0)) {
errno = ERANGE; errno = ERANGE;