Commit 89996e1f authored by Ken Thompson's avatar Ken Thompson

truncating of float constants when

used in float64 or float32 contexts

R=r
OCL=20297
CL=20297
parent acfd1fd4
...@@ -5,6 +5,34 @@ ...@@ -5,6 +5,34 @@
#include "go.h" #include "go.h"
#define TUP(x,y) (((x)<<16)|(y)) #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 void
convlit(Node *n, Type *t) convlit(Node *n, Type *t)
{ {
...@@ -90,15 +118,18 @@ convlit(Node *n, Type *t) ...@@ -90,15 +118,18 @@ convlit(Node *n, Type *t)
if(isfloat[et]) { if(isfloat[et]) {
// int to float // int to float
Mpint *xv; Mpint *xv;
Mpflt *fv;
xv = n->val.u.xval; xv = n->val.u.xval;
if(mpcmpfixflt(xv, minfltval[et]) < 0) if(mpcmpfixflt(xv, minfltval[et]) < 0)
goto bad2; goto bad2;
if(mpcmpfixflt(xv, maxfltval[et]) > 0) if(mpcmpfixflt(xv, maxfltval[et]) > 0)
goto bad2; goto bad2;
n->val.u.fval = mal(sizeof(*n->val.u.fval)); fv = mal(sizeof(*n->val.u.fval));
mpmovefixflt(n->val.u.fval, xv); n->val.u.fval = fv;
mpmovefixflt(fv, xv);
n->val.ctype = CTFLT; n->val.ctype = CTFLT;
truncfltlit(fv, t);
break; break;
} }
goto bad1; goto bad1;
...@@ -126,8 +157,6 @@ convlit(Node *n, Type *t) ...@@ -126,8 +157,6 @@ convlit(Node *n, Type *t)
} }
if(isfloat[et]) { if(isfloat[et]) {
// float to float // float to float
double d;
float f;
Mpflt *fv; Mpflt *fv;
fv = n->val.u.fval; fv = n->val.u.fval;
...@@ -135,24 +164,13 @@ convlit(Node *n, Type *t) ...@@ -135,24 +164,13 @@ convlit(Node *n, Type *t)
goto bad2; goto bad2;
if(mpcmpfltflt(fv, maxfltval[et]) > 0) if(mpcmpfltflt(fv, maxfltval[et]) > 0)
goto bad2; goto bad2;
// switch(et) { truncfltlit(fv, t);
// case TFLOAT64:
// d = mpgetflt(fv);
// mpmovecflt(fv, d);
// break;
//
// case TFLOAT32:
// d = mpgetflt(fv);
// f = d;
// d = f;
// mpmovecflt(fv, d);
// break;
// }
break; break;
} }
goto bad1; goto bad1;
} }
n->type = t; n->type = t;
return; return;
bad1: bad1:
...@@ -442,6 +460,7 @@ ret: ...@@ -442,6 +460,7 @@ ret:
} else } else
if(wl == Wlitfloat) { if(wl == Wlitfloat) {
n->val.u.fval = fval; n->val.u.fval = fval;
truncfltlit(fval, n->type);
} }
} }
......
...@@ -176,11 +176,15 @@ mpgetflt(Mpflt *a) ...@@ -176,11 +176,15 @@ mpgetflt(Mpflt *a)
mpnorm(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); mpshiftfix(&a->val, 1);
a->exp -= 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 // pick up the mantissa in a uvlong
s = 63; s = 63;
v = 0; v = 0;
...@@ -191,13 +195,14 @@ mpgetflt(Mpflt *a) ...@@ -191,13 +195,14 @@ mpgetflt(Mpflt *a)
if(s > 0) if(s > 0)
v = (v<<s) | (a->val.a[i]>>(Mpscale-s)); v = (v<<s) | (a->val.a[i]>>(Mpscale-s));
// should do this in multi precision
// 63 bits of mantissa being rounded to 53 // 63 bits of mantissa being rounded to 53
// should do this in multi precision
if((v&0x3ffULL) != 0x200ULL || (v&0x400) != 0) if((v&0x3ffULL) != 0x200ULL || (v&0x400) != 0)
v += 0x200ULL; // round v += 0x200ULL; // round toward even
v &= ~0x3ffULL;
v >>= 10;
f = (double)(v); f = (double)(v);
f = ldexp(f, Mpnorm*Mpscale + a->exp - 63); f = ldexp(f, Mpnorm*Mpscale + a->exp - 53);
if(a->val.neg) if(a->val.neg)
f = -f; f = -f;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment