diff options
author | Ondřej Surý <ondrej@sury.org> | 2011-01-17 12:40:45 +0100 |
---|---|---|
committer | Ondřej Surý <ondrej@sury.org> | 2011-01-17 12:40:45 +0100 |
commit | 3e45412327a2654a77944249962b3652e6142299 (patch) | |
tree | bc3bf69452afa055423cbe0c5cfa8ca357df6ccf /src/cmd/gc/mparith1.c | |
parent | c533680039762cacbc37db8dc7eed074c3e497be (diff) | |
download | golang-upstream/2011.01.12.tar.gz |
Imported Upstream version 2011.01.12upstream/2011.01.12
Diffstat (limited to 'src/cmd/gc/mparith1.c')
-rw-r--r-- | src/cmd/gc/mparith1.c | 42 |
1 files changed, 40 insertions, 2 deletions
diff --git a/src/cmd/gc/mparith1.c b/src/cmd/gc/mparith1.c index 8110e77b9..6cd4e2500 100644 --- a/src/cmd/gc/mparith1.c +++ b/src/cmd/gc/mparith1.c @@ -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) { @@ -188,6 +218,8 @@ static double tab[] = { 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7 }; static void mppow10flt(Mpflt *a, int p) { + if(p < 0) + abort(); if(p < nelem(tab)) { mpmovecflt(a, tab[p]); return; @@ -267,6 +299,10 @@ mpatoflt(Mpflt *a, char *as) } if(c >= '0' && c <= '9') { ex = ex*10 + (c-'0'); + if(ex > 1e8) { + yyerror("exponent out of range"); + errorexit(); + } continue; } break; @@ -439,6 +475,8 @@ Fconv(Fmt *fp) // for well in range, convert to double and use print's %g if(-900 < fvp->exp && fvp->exp < 900) { d = mpgetflt(fvp); + if(d >= 0 && (fp->flags & FmtSign)) + fmtprint(fp, "+"); return fmtprint(fp, "%g", d); } // TODO(rsc): for well out of range, print |