]> Cypherpunks repositories - gostls13.git/commitdiff
truncating of float constants when
authorKen Thompson <ken@golang.org>
Wed, 3 Dec 2008 01:03:47 +0000 (17:03 -0800)
committerKen Thompson <ken@golang.org>
Wed, 3 Dec 2008 01:03:47 +0000 (17:03 -0800)
used in float64 or float32 contexts

R=r
OCL=20297
CL=20297

src/cmd/gc/const.c
src/cmd/gc/mparith3.c

index 3a3fef191d256ae848a20d2bfe3d1fbf84171dc6..ad8607794e49706d2fed0a70ef308893e9a96738 100644 (file)
@@ -5,6 +5,34 @@
 #include       "go.h"
 #define        TUP(x,y)        (((x)<<16)|(y))
 
+void
+truncfltlit(Mpflt *fv, Type *t)
+{
+       double d;
+       float f;
+
+       if(t == T)
+               return;
+
+       // convert large precision literal floating
+       // into limited precision (float64 or float32)
+       // botch -- this assumes that compiler fp
+       //    has same precision as runtime fp
+       switch(t->etype) {
+       case TFLOAT64:
+               d = mpgetflt(fv);
+               mpmovecflt(fv, d);
+               break;
+
+       case TFLOAT32:
+               d = mpgetflt(fv);
+               f = d;
+               d = f;
+               mpmovecflt(fv, d);
+               break;
+       }
+}
+
 void
 convlit(Node *n, Type *t)
 {
@@ -90,15 +118,18 @@ convlit(Node *n, Type *t)
                if(isfloat[et]) {
                        // int to float
                        Mpint *xv;
+                       Mpflt *fv;
 
                        xv = n->val.u.xval;
                        if(mpcmpfixflt(xv, minfltval[et]) < 0)
                                goto bad2;
                        if(mpcmpfixflt(xv, maxfltval[et]) > 0)
                                goto bad2;
-                       n->val.u.fval = mal(sizeof(*n->val.u.fval));
-                       mpmovefixflt(n->val.u.fval, xv);
+                       fv = mal(sizeof(*n->val.u.fval));
+                       n->val.u.fval = fv;
+                       mpmovefixflt(fv, xv);
                        n->val.ctype = CTFLT;
+                       truncfltlit(fv, t);
                        break;
                }
                goto bad1;
@@ -126,8 +157,6 @@ convlit(Node *n, Type *t)
                }
                if(isfloat[et]) {
                        // float to float
-                       double d;
-                       float f;
                        Mpflt *fv;
 
                        fv = n->val.u.fval;
@@ -135,24 +164,13 @@ convlit(Node *n, Type *t)
                                goto bad2;
                        if(mpcmpfltflt(fv, maxfltval[et]) > 0)
                                goto bad2;
-//                     switch(et) {
-//                     case TFLOAT64:
-//                             d = mpgetflt(fv);
-//                             mpmovecflt(fv, d);
-//                             break;
-//
-//                     case TFLOAT32:
-//                             d = mpgetflt(fv);
-//                             f = d;
-//                             d = f;
-//                             mpmovecflt(fv, d);
-//                             break;
-//                     }
+                       truncfltlit(fv, t);
                        break;
                }
                goto bad1;
        }
        n->type = t;
+       
        return;
 
 bad1:
@@ -442,6 +460,7 @@ ret:
        } else
        if(wl == Wlitfloat) {
                n->val.u.fval = fval;
+               truncfltlit(fval, n->type);
        }
 }
 
index 1bf39c9fb43d947283ec226375c687e22d681790..7098ba68b24fd24bb8fabdaa4a2e6734fc9cf9e4 100644 (file)
@@ -176,11 +176,15 @@ mpgetflt(Mpflt *a)
                mpnorm(a);
        }
 
-       while((a->val.a[Mpnorm-1] & (1L<<(Mpscale-1))) == 0) {
+       while((a->val.a[Mpnorm-1] & Mpsign) == 0) {
                mpshiftfix(&a->val, 1);
                a->exp -= 1;
        }
 
+       // the magic numbers (64, 63, 53, 10) are
+       // IEEE specific. this should be done machine
+       // independently or in the 6g half of the compiler
+
        // pick up the mantissa in a uvlong
        s = 63;
        v = 0;
@@ -191,13 +195,14 @@ mpgetflt(Mpflt *a)
        if(s > 0)
                v = (v<<s) | (a->val.a[i]>>(Mpscale-s));
 
-       // should do this in multi precision
        // 63 bits of mantissa being rounded to 53
+       // should do this in multi precision
        if((v&0x3ffULL) != 0x200ULL || (v&0x400) != 0)
-               v += 0x200ULL;          // round
-       v &= ~0x3ffULL;
+               v += 0x200ULL;          // round toward even
+
+       v >>= 10;
        f = (double)(v);
-       f = ldexp(f, Mpnorm*Mpscale + a->exp - 63);
+       f = ldexp(f, Mpnorm*Mpscale + a->exp - 53);
 
        if(a->val.neg)
                f = -f;