summaryrefslogtreecommitdiff
path: root/src/cmd/gc/mparith3.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/gc/mparith3.c')
-rw-r--r--src/cmd/gc/mparith3.c30
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)