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>
static
ten_mult(struct EXTEND *e)
{
struct EXTEND e1 = *e;
e1.exp++;
e->exp += 3;
add_ext(e, &e1, e);
}
#define NDIGITS 128
#define NSIGNIFICANT 19
char *
_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 */
static char buf[NDIGITS+1];
struct EXTEND m;
register char *p = buf;
register char *pe;
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);
*decpt -= findex * TP;
/* here, value >= 10 ** -28 */
mul_ext(e, &ten_powers[1], e);
ten_mult(e);
(*decpt)--;
pp = &r_ten_powers[0];
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;
if (pe > &buf[NDIGITS]) pe = &buf[NDIGITS];
}
m.exp = -62;
m.sign = 0;
m.m1 = 0xA0000000;
m.m2 = 0;
while (p <= pe) {
struct EXTEND oneminm;
if (p - pe > NSIGNIFICANT) {
findex = 0;
e->m1 = 0;
}
if (findex) {
struct EXTEND tc, oldtc;
int count = 0;
@ -621,20 +643,31 @@ _ext_str_cvt(struct EXTEND *e, int ndigit, int *decpt, int *sign, int ecvtflag)
findex--;
continue;
}
if (e->exp >= 0 && e->m1 != 0) {
struct EXTEND x;
if (e->m1) {
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.sign = 1;
x.m1 = e->m1>>(31-e->exp);
*p++ = (x.m1) + '0';
if (x.m1) {
x.m2 = 0; x.exp = e->exp;
x.sign = 1;
x.m1 = e->m1>>(31-e->exp);
*p++ = (x.m1) + '0';
x.m1 = x.m1 << (31-e->exp);
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';
if (e->m1) mul_ext(e, &ten_powers[1], e);
}
if (pe >= buf) {
p = pe;
@ -670,18 +703,11 @@ _dbl_ext_cvt(double value, struct EXTEND *e)
e->sign = value < 0.0;
if (e->sign) value = -value;
e->exp = exponent - 1;
e->m1 = 0;
e->m2 = 0;
for (i = 64; i > 0 && value != 0; i--) {
double ipart;
b64_sft(&(e->mantissa),-1);
value = modf(2.0*value, &ipart);
if (ipart) {
e->m2 |= 1;
}
}
if (i > 0) b64_sft(&(e->mantissa),-i);
value *= 4294967296.0;
e->m1 = value;
value -= e->m1;
value *= 4294967296.0;
e->m2 = value;
}
static struct EXTEND max_d;
@ -705,7 +731,7 @@ _ext_dbl_cvt(struct EXTEND *e)
f = HUGE_VAL;
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 (f == 0.0 && (e->m1 != 0 || e->m2 != 0)) {
errno = ERANGE;