]> Cypherpunks repositories - gostls13.git/commitdiff
1. got 29 (Mpscale) more bits of precision
authorKen Thompson <ken@golang.org>
Sat, 17 Jul 2010 23:32:40 +0000 (16:32 -0700)
committerKen Thompson <ken@golang.org>
Sat, 17 Jul 2010 23:32:40 +0000 (16:32 -0700)
out of floating constant multiply
2. added rounding code to "const fix=float"
to allow up to 29 (Mpscale) bits of
slop and still get an exact fixed constant.

fixes #931

R=rsc
CC=golang-dev
https://golang.org/cl/1692055

src/cmd/gc/mparith1.c
src/cmd/gc/mparith2.c
src/cmd/gc/mparith3.c

index 8110e77b98d78cead3f555d66f6bc0e6277fd984..14226d6a9a025bfb2608e2bc1ef75f764809a4db 100644 (file)
@@ -156,10 +156,11 @@ mpmovefixflt(Mpflt *a, Mpint *b)
 
 // convert (truncate) b to a.
 // return -1 (but still convert) if b was non-integer.
-int
-mpmovefltfix(Mpint *a, Mpflt *b)
+static int
+mpexactfltfix(Mpint *a, Mpflt *b)
 {
        Mpflt f;
+
        *a = b->val;
        mpshiftfix(a, b->exp);
        if(b->exp < 0) {
@@ -172,6 +173,35 @@ mpmovefltfix(Mpint *a, Mpflt *b)
        return 0;
 }
 
+int
+mpmovefltfix(Mpint *a, Mpflt *b)
+{
+       Mpflt f;
+       int i;
+
+       if(mpexactfltfix(a, b) == 0)
+               return 0;
+
+       // try rounding down a little
+       f = *b;
+       f.val.a[0] = 0;
+       if(mpexactfltfix(a, &f) == 0)
+               return 0;
+
+       // try rounding up a little
+       for(i=1; i<Mpprec; i++) {
+               f.val.a[i]++;
+               if(f.val.a[i] != Mpbase)
+                       break;
+               f.val.a[i] = 0;
+       }
+       mpnorm(&f);
+       if(mpexactfltfix(a, &f) == 0)
+               return 0;
+
+       return -1;
+}
+
 void
 mpmovefixfix(Mpint *a, Mpint *b)
 {
index b025917fa8f5c9707305b3579faa185e65d4c465..67375adb173511452612dc36e190e82d3c99aa60 100644 (file)
@@ -319,7 +319,11 @@ mpmulfract(Mpint *a, Mpint *b)
        s.neg = 0;
        mpmovecfix(&q, 0);
 
-       for(i=0; i<Mpprec; i++) {
+       x = *--a1;
+       if(x != 0)
+               yyerror("mpmulfract not normal");
+
+       for(i=0; i<Mpprec-1; i++) {
                x = *--a1;
                if(x == 0) {
                        mprshw(&s);
index b9cd4ea847572534c295345ba820dbe2b760e68d..5ee8b0308f8bec4bdc6cdd5702f05aeeb497dd4d 100644 (file)
@@ -109,7 +109,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)