diff options
Diffstat (limited to 'src/cmd/gc/mparith3.c')
-rw-r--r-- | src/cmd/gc/mparith3.c | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/src/cmd/gc/mparith3.c b/src/cmd/gc/mparith3.c index b9cd4ea84..7b7e66668 100644 --- a/src/cmd/gc/mparith3.c +++ b/src/cmd/gc/mparith3.c @@ -27,16 +27,36 @@ sigfig(Mpflt *a) void mpnorm(Mpflt *a) { - int s; + int s, os; + long x; - s = sigfig(a); - if(s == 0) { + os = sigfig(a); + if(os == 0) { // zero a->exp = 0; a->val.neg = 0; return; } - s = (Mpnorm-s) * Mpscale; + + // this will normalize to the nearest word + x = a->val.a[os-1]; + s = (Mpnorm-os) * Mpscale; + + // further normalize to the nearest bit + for(;;) { + x <<= 1; + if(x & Mpbase) + break; + s++; + if(x == 0) { + // this error comes from trying to + // convert an Inf or something + // where the initial x=0x80000000 + s = (Mpnorm-os) * Mpscale; + break; + } + } + mpshiftfix(&a->val, s); a->exp -= s; } @@ -109,7 +129,7 @@ mpmulfltflt(Mpflt *a, Mpflt *b) } mpmulfract(&a->val, &b->val); - a->exp = (a->exp + b->exp) + Mpscale*Mpprec - 1; + a->exp = (a->exp + b->exp) + Mpscale*Mpprec - Mpscale - 1; mpnorm(a); if(Mpdebug) |