diff options
Diffstat (limited to 'src/cmd/gc/mparith1.c')
-rw-r--r-- | src/cmd/gc/mparith1.c | 509 |
1 files changed, 0 insertions, 509 deletions
diff --git a/src/cmd/gc/mparith1.c b/src/cmd/gc/mparith1.c deleted file mode 100644 index 6cd4e2500..000000000 --- a/src/cmd/gc/mparith1.c +++ /dev/null @@ -1,509 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -#include "go.h" - -/// uses arithmetic - -int -mpcmpfixflt(Mpint *a, Mpflt *b) -{ - char buf[500]; - Mpflt c; - - snprint(buf, sizeof(buf), "%B", a); - mpatoflt(&c, buf); - return mpcmpfltflt(&c, b); -} - -int -mpcmpfltfix(Mpflt *a, Mpint *b) -{ - char buf[500]; - Mpflt c; - - snprint(buf, sizeof(buf), "%B", b); - mpatoflt(&c, buf); - return mpcmpfltflt(a, &c); -} - -int -mpcmpfixfix(Mpint *a, Mpint *b) -{ - Mpint c; - - mpmovefixfix(&c, a); - mpsubfixfix(&c, b); - return mptestfix(&c); -} - -int -mpcmpfixc(Mpint *b, vlong c) -{ - Mpint a; - - mpmovecfix(&a, c); - return mpcmpfixfix(&a, b); -} - -int -mpcmpfltflt(Mpflt *a, Mpflt *b) -{ - Mpflt c; - - mpmovefltflt(&c, a); - mpsubfltflt(&c, b); - return mptestflt(&c); -} - -int -mpcmpfltc(Mpflt *b, double c) -{ - Mpflt a; - - mpmovecflt(&a, c); - return mpcmpfltflt(&a, b); -} - -void -mpsubfixfix(Mpint *a, Mpint *b) -{ - mpnegfix(a); - mpaddfixfix(a, b); - mpnegfix(a); -} - -void -mpsubfltflt(Mpflt *a, Mpflt *b) -{ - mpnegflt(a); - mpaddfltflt(a, b); - mpnegflt(a); -} - -void -mpaddcfix(Mpint *a, vlong c) -{ - Mpint b; - - mpmovecfix(&b, c); - mpaddfixfix(a, &b); -} - -void -mpaddcflt(Mpflt *a, double c) -{ - Mpflt b; - - mpmovecflt(&b, c); - mpaddfltflt(a, &b); -} - -void -mpmulcfix(Mpint *a, vlong c) -{ - Mpint b; - - mpmovecfix(&b, c); - mpmulfixfix(a, &b); -} - -void -mpmulcflt(Mpflt *a, double c) -{ - Mpflt b; - - mpmovecflt(&b, c); - mpmulfltflt(a, &b); -} - -void -mpdivfixfix(Mpint *a, Mpint *b) -{ - Mpint q, r; - - mpdivmodfixfix(&q, &r, a, b); - mpmovefixfix(a, &q); -} - -void -mpmodfixfix(Mpint *a, Mpint *b) -{ - Mpint q, r; - - mpdivmodfixfix(&q, &r, a, b); - mpmovefixfix(a, &r); -} - -void -mpcomfix(Mpint *a) -{ - Mpint b; - - mpmovecfix(&b, 1); - mpnegfix(a); - mpsubfixfix(a, &b); -} - -void -mpmovefixflt(Mpflt *a, Mpint *b) -{ - a->val = *b; - a->exp = 0; - mpnorm(a); -} - -// convert (truncate) b to a. -// return -1 (but still convert) if b was non-integer. -static int -mpexactfltfix(Mpint *a, Mpflt *b) -{ - Mpflt f; - - *a = b->val; - mpshiftfix(a, b->exp); - if(b->exp < 0) { - f.val = *a; - f.exp = 0; - mpnorm(&f); - if(mpcmpfltflt(b, &f) != 0) - return -1; - } - 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) -{ - *a = *b; -} - -void -mpmovefltflt(Mpflt *a, Mpflt *b) -{ - *a = *b; -} - -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; - } - mppow10flt(a, p>>1); - mpmulfltflt(a, a); - if(p & 1) - mpmulcflt(a, 10); -} - -// -// floating point input -// required syntax is [+-]d*[.]d*[e[+-]d*] -// -void -mpatoflt(Mpflt *a, char *as) -{ - Mpflt b; - int dp, c, f, ef, ex, eb; - char *s; - - s = as; - dp = 0; /* digits after decimal point */ - f = 0; /* sign */ - ex = 0; /* exponent */ - eb = 0; /* binary point */ - - mpmovecflt(a, 0.0); - for(;;) { - switch(c = *s++) { - default: - goto bad; - - case '-': - f = 1; - - case ' ': - case '\t': - case '+': - continue; - - case '.': - dp = 1; - continue; - - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '0': - mpmulcflt(a, 10); - mpaddcflt(a, c-'0'); - if(dp) - dp++; - continue; - - case 'P': - case 'p': - eb = 1; - - case 'E': - case 'e': - ex = 0; - ef = 0; - for(;;) { - c = *s++; - if(c == '+' || c == ' ' || c == '\t') - continue; - if(c == '-') { - ef = 1; - continue; - } - if(c >= '0' && c <= '9') { - ex = ex*10 + (c-'0'); - if(ex > 1e8) { - yyerror("exponent out of range"); - errorexit(); - } - continue; - } - break; - } - if(ef) - ex = -ex; - - case 0: - break; - } - break; - } - - if(eb) { - if(dp) - goto bad; - a->exp += ex; - goto out; - } - - if(dp) - dp--; - if(mpcmpfltc(a, 0.0) != 0) { - if(ex >= dp) { - mppow10flt(&b, ex-dp); - mpmulfltflt(a, &b); - } else { - mppow10flt(&b, dp-ex); - mpdivfltflt(a, &b); - } - } - -out: - if(f) - mpnegflt(a); - return; - -bad: - yyerror("set ovf in mpatof"); - mpmovecflt(a, 0.0); -} - -// -// fixed point input -// required syntax is [+-][0[x]]d* -// -void -mpatofix(Mpint *a, char *as) -{ - int c, f; - char *s; - - s = as; - f = 0; - mpmovecfix(a, 0); - - c = *s++; - switch(c) { - case '-': - f = 1; - - case '+': - c = *s++; - if(c != '0') - break; - - case '0': - goto oct; - } - - while(c) { - if(c >= '0' && c <= '9') { - mpmulcfix(a, 10); - mpaddcfix(a, c-'0'); - c = *s++; - continue; - } - goto bad; - } - goto out; - -oct: - c = *s++; - if(c == 'x' || c == 'X') - goto hex; - while(c) { - if(c >= '0' && c <= '7') { - mpmulcfix(a, 8); - mpaddcfix(a, c-'0'); - c = *s++; - continue; - } - goto bad; - } - goto out; - -hex: - c = *s++; - while(c) { - if(c >= '0' && c <= '9') { - mpmulcfix(a, 16); - mpaddcfix(a, c-'0'); - c = *s++; - continue; - } - if(c >= 'a' && c <= 'f') { - mpmulcfix(a, 16); - mpaddcfix(a, c+10-'a'); - c = *s++; - continue; - } - if(c >= 'A' && c <= 'F') { - mpmulcfix(a, 16); - mpaddcfix(a, c+10-'A'); - c = *s++; - continue; - } - goto bad; - } - -out: - if(f) - mpnegfix(a); - return; - -bad: - yyerror("set ovf in mpatov: %s", as); - mpmovecfix(a, 0); -} - -int -Bconv(Fmt *fp) -{ - char buf[500], *p; - Mpint *xval, q, r, ten; - int f; - - xval = va_arg(fp->args, Mpint*); - mpmovefixfix(&q, xval); - f = 0; - if(mptestfix(&q) < 0) { - f = 1; - mpnegfix(&q); - } - mpmovecfix(&ten, 10); - - p = &buf[sizeof(buf)]; - *--p = 0; - for(;;) { - mpdivmodfixfix(&q, &r, &q, &ten); - *--p = mpgetfix(&r) + '0'; - if(mptestfix(&q) <= 0) - break; - } - if(f) - *--p = '-'; - return fmtstrcpy(fp, p); -} - -int -Fconv(Fmt *fp) -{ - char buf[500]; - Mpflt *fvp, fv; - double d; - - fvp = va_arg(fp->args, Mpflt*); - if(fp->flags & FmtSharp) { - // alternate form - decimal for error messages. - // 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 - // an approximation like 1.234e1000 - } - - if(sigfig(fvp) == 0) { - snprint(buf, sizeof(buf), "0p+0"); - goto out; - } - fv = *fvp; - - while(fv.val.a[0] == 0) { - mpshiftfix(&fv.val, -Mpscale); - fv.exp += Mpscale; - } - while((fv.val.a[0]&1) == 0) { - mpshiftfix(&fv.val, -1); - fv.exp += 1; - } - - if(fv.exp >= 0) { - snprint(buf, sizeof(buf), "%Bp+%d", &fv.val, fv.exp); - goto out; - } - snprint(buf, sizeof(buf), "%Bp-%d", &fv.val, -fv.exp); - -out: - return fmtstrcpy(fp, buf); -} |