summaryrefslogtreecommitdiff
path: root/src/cmd/gc/mparith3.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/gc/mparith3.c')
-rw-r--r--src/cmd/gc/mparith3.c313
1 files changed, 0 insertions, 313 deletions
diff --git a/src/cmd/gc/mparith3.c b/src/cmd/gc/mparith3.c
deleted file mode 100644
index b11a4f5f1..000000000
--- a/src/cmd/gc/mparith3.c
+++ /dev/null
@@ -1,313 +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"
-
-/*
- * returns the leading non-zero
- * word of the number
- */
-int
-sigfig(Mpflt *a)
-{
- int i;
-
- for(i=Mpprec-1; i>=0; i--)
- if(a->val.a[i] != 0)
- break;
-//print("sigfig %d %d\n", i-z+1, z);
- return i+1;
-}
-
-/*
- * shifts the leading non-zero
- * word of the number to Mpnorm
- */
-void
-mpnorm(Mpflt *a)
-{
- int s, os;
- long x;
-
- os = sigfig(a);
- if(os == 0) {
- // zero
- a->exp = 0;
- a->val.neg = 0;
- return;
- }
-
- // this will normalize to the nearest word
- x = a->val.a[os-1];
- s = (Mpnorm-os) * Mpscale;
-
- // further normalize to the nearest bit
- for(;;) {
- x <<= 1;
- if(x & Mpbase)
- break;
- s++;
- if(x == 0) {
- // this error comes from trying to
- // convert an Inf or something
- // where the initial x=0x80000000
- s = (Mpnorm-os) * Mpscale;
- break;
- }
- }
-
- mpshiftfix(&a->val, s);
- a->exp -= s;
-}
-
-/// implements float arihmetic
-
-void
-mpaddfltflt(Mpflt *a, Mpflt *b)
-{
- int sa, sb, s;
- Mpflt c;
-
- if(Mpdebug)
- print("\n%F + %F", a, b);
-
- sa = sigfig(a);
- if(sa == 0) {
- mpmovefltflt(a, b);
- goto out;
- }
-
- sb = sigfig(b);
- if(sb == 0)
- goto out;
-
- s = a->exp - b->exp;
- if(s > 0) {
- // a is larger, shift b right
- mpmovefltflt(&c, b);
- mpshiftfix(&c.val, -s);
- mpaddfixfix(&a->val, &c.val);
- goto out;
- }
- if(s < 0) {
- // b is larger, shift a right
- mpshiftfix(&a->val, s);
- a->exp -= s;
- mpaddfixfix(&a->val, &b->val);
- goto out;
- }
- mpaddfixfix(&a->val, &b->val);
-
-out:
- mpnorm(a);
- if(Mpdebug)
- print(" = %F\n\n", a);
-}
-
-void
-mpmulfltflt(Mpflt *a, Mpflt *b)
-{
- int sa, sb;
-
- if(Mpdebug)
- print("%F\n * %F\n", a, b);
-
- sa = sigfig(a);
- if(sa == 0) {
- // zero
- a->exp = 0;
- a->val.neg = 0;
- return;
- }
-
- sb = sigfig(b);
- if(sb == 0) {
- // zero
- mpmovefltflt(a, b);
- return;
- }
-
- mpmulfract(&a->val, &b->val);
- a->exp = (a->exp + b->exp) + Mpscale*Mpprec - Mpscale - 1;
-
- mpnorm(a);
- if(Mpdebug)
- print(" = %F\n\n", a);
-}
-
-void
-mpdivfltflt(Mpflt *a, Mpflt *b)
-{
- int sa, sb;
- Mpflt c;
-
- if(Mpdebug)
- print("%F\n / %F\n", a, b);
-
- sb = sigfig(b);
- if(sb == 0) {
- // zero and ovfl
- a->exp = 0;
- a->val.neg = 0;
- a->val.ovf = 1;
- yyerror("mpdivfltflt divide by zero");
- return;
- }
-
- sa = sigfig(a);
- if(sa == 0) {
- // zero
- a->exp = 0;
- a->val.neg = 0;
- return;
- }
-
- // adjust b to top
- mpmovefltflt(&c, b);
- mpshiftfix(&c.val, Mpscale);
-
- // divide
- mpdivfract(&a->val, &c.val);
- a->exp = (a->exp-c.exp) - Mpscale*(Mpprec-1) + 1;
-
- mpnorm(a);
- if(Mpdebug)
- print(" = %F\n\n", a);
-}
-
-double
-mpgetflt(Mpflt *a)
-{
- int s, i, e;
- uvlong v, vm;
- double f;
-
- if(a->val.ovf)
- yyerror("mpgetflt ovf");
-
- s = sigfig(a);
- if(s == 0)
- return 0;
-
- if(s != Mpnorm) {
- yyerror("mpgetflt norm");
- mpnorm(a);
- }
-
- while((a->val.a[Mpnorm-1] & Mpsign) == 0) {
- mpshiftfix(&a->val, 1);
- a->exp -= 1;
- }
-
- // the magic numbers (64, 63, 53, 10, -1074) are
- // IEEE specific. this should be done machine
- // independently or in the 6g half of the compiler
-
- // pick up the mantissa and a rounding bit in a uvlong
- s = 53+1;
- v = 0;
- for(i=Mpnorm-1; s>=Mpscale; i--) {
- v = (v<<Mpscale) | a->val.a[i];
- s -= Mpscale;
- }
- vm = v;
- if(s > 0)
- vm = (vm<<s) | (a->val.a[i]>>(Mpscale-s));
-
- // continue with 64 more bits
- s += 64;
- for(; s>=Mpscale; i--) {
- v = (v<<Mpscale) | a->val.a[i];
- s -= Mpscale;
- }
- if(s > 0)
- v = (v<<s) | (a->val.a[i]>>(Mpscale-s));
-
- // gradual underflow
- e = Mpnorm*Mpscale + a->exp - 53;
- if(e < -1074) {
- s = -e - 1074;
- if(s > 54)
- s = 54;
- v |= vm & ((1ULL<<s) - 1);
- vm >>= s;
- e = -1074;
- }
-
-//print("vm=%.16llux v=%.16llux\n", vm, v);
- // round toward even
- if(v != 0 || (vm&2ULL) != 0)
- vm = (vm>>1) + (vm&1ULL);
- else
- vm >>= 1;
-
- f = (double)(vm);
- f = ldexp(f, e);
-
- if(a->val.neg)
- f = -f;
- return f;
-}
-
-void
-mpmovecflt(Mpflt *a, double c)
-{
- int i;
- double f;
- long l;
-
- if(Mpdebug)
- print("\nconst %g", c);
- mpmovecfix(&a->val, 0);
- a->exp = 0;
- if(c == 0)
- goto out;
- if(c < 0) {
- a->val.neg = 1;
- c = -c;
- }
-
- f = frexp(c, &i);
- a->exp = i;
-
- for(i=0; i<10; i++) {
- f = f*Mpbase;
- l = floor(f);
- f = f - l;
- a->exp -= Mpscale;
- a->val.a[0] = l;
- if(f == 0)
- break;
- mpshiftfix(&a->val, Mpscale);
- }
-
-out:
- mpnorm(a);
- if(Mpdebug)
- print(" = %F\n", a);
-}
-
-void
-mpnegflt(Mpflt *a)
-{
- a->val.neg ^= 1;
-}
-
-int
-mptestflt(Mpflt *a)
-{
- int s;
-
- if(Mpdebug)
- print("\n%F?", a);
- s = sigfig(a);
- if(s != 0) {
- s = +1;
- if(a->val.neg)
- s = -1;
- }
- if(Mpdebug)
- print(" = %d\n", s);
- return s;
-}