From: Robert Griesemer Date: Tue, 4 Nov 2008 22:08:47 +0000 (-0800) Subject: get rid of bignum leftovers X-Git-Tag: weekly.2009-11-06~2802 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=17596948e355e3b875472b7e754d72adddd8e606;p=gostls13.git get rid of bignum leftovers R=r OCL=18475 CL=18475 --- diff --git a/usr/gri/bignum/Makefile b/usr/gri/bignum/Makefile deleted file mode 100644 index d83ea809c0..0000000000 --- a/usr/gri/bignum/Makefile +++ /dev/null @@ -1,20 +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. - -G=6g -L=6l - -bignum_test: bignum_test.6 - $(L) -o bignum_test bignum_test.6 - -test: bignum_test - ./bignum_test - -clean: - rm -f bignum_test *.6 *~ - -bignum_test.6: bignum.6 - -%.6: %.go - $(G) $(F) $< diff --git a/usr/gri/bignum/integer.go b/usr/gri/bignum/integer.go deleted file mode 100755 index f6184c4cbd..0000000000 --- a/usr/gri/bignum/integer.go +++ /dev/null @@ -1,635 +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. - -package Integer - -const ValueLen = 1000; -type Word uint32 -type Value *[ValueLen]Word -export type IntegerImpl struct { - val Value -} -export type Integer *IntegerImpl - -const N = 4; -const H = 1 -const L = 28; -const M = 1 << L - 1; - - -// ---------------------------------------------------------------------------- -// Support - -// TODO What are we going to about asserts? -func ASSERT(p bool) { - if !p { - panic("ASSERT failed"); - } -} - - -func CHECK(p bool) { - if !p { - panic("CHECK failed"); - } -} - - -func UNIMPLEMENTED(s string) { - panic("UNIMPLEMENTED: ", s); -} - - -// ---------------------------------------------------------------------------- -// - -// TODO "len" is a reserved word at the moment - I think that's wrong -func len_(x Value) int { - l := int(x[0]); - if l < 0 { return -l; } - return l; -} - - -func set_len(x Value, len_ int) { - x[0] = Word(len_); -} - - -func alloc(len_ int) Value { - ASSERT(len_ >= 0); - z := new([ValueLen] Word); - set_len(z, len_); - return z; -} - - -func sign(x Value) bool { - return int(x[0]) < 0; -} - - -func zero(x Value) bool { - return x[0] == 0; -} - - -func neg(x Value) { - x[0] = Word(-int(x[0])); -} - - -// ---------------------------------------------------------------------------- -// Unsigned ops - -func make(x int) Value; - - -func Update(x Word) (z, c Word) { - // z = x & M; - // c = x >> L; - return x & M, x >> L; -} - - -func uadd(x, y Value) Value { - xl := len_(x); - yl := len_(y); - if xl < yl { - return uadd(y, x); - } - ASSERT(xl >= yl); - z := alloc(xl + 1); - - i := 0; - c := Word(0); - for i < yl { z[i + H], c = Update(x[i + H] + y[i + H] + c); i++; } - for i < xl { z[i + H], c = Update(x[i + H] + c); i++; } - if c != 0 { z[i + H] = c; i++; } - set_len(z, i); - - return z; -} - - -func usub(x, y Value) Value { - xl := len_(x); - yl := len_(y); - if xl < yl { - return uadd(y, x); - } - ASSERT(xl >= yl); - z := alloc(xl + 1); - - i := 0; - c := Word(0); - for i < yl { z[i + H], c = Update(x[i + H] - y[i + H] + c); i++; } - for i < xl { z[i + H], c = Update(x[i + H] + c); i++; } - ASSERT(c == 0); // usub(x, y) must be called with x >= y - for i > 0 && z[i - 1 + H] == 0 { i--; } - set_len(z, i); - - return z; -} - - -// Computes x = x*a + c (in place) for "small" a's. -func umul_add(x Value, a, c Word) Value { - CHECK(0 <= a && a < (1 << N)); - CHECK(0 <= c && c < (1 << N)); - if (zero(x) || a == 0) && c == 0 { - return make(0); - } - xl := len_(x); - - z := alloc(xl + 1); - i := 0; - for i < xl { z[i + H], c = Update(x[i + H] * a + c); i++; } - if c != 0 { z[i + H] = c; i++; } - set_len(z, i); - - return z; -} - - -// Computes x = x div d (in place) for "small" d's. Returns x mod d. -func umod(x Value, d Word) Word { - CHECK(0 < d && d < (1 << N)); - xl := len_(x); - c := Word(0); - - i := xl; - for i > 0 { - i--; - c = c << L + x[i + H]; - - q := c / d; - x[i + H] = q; - - //x[i + H] = c / d; // BUG - - c = c % d; - } - if xl > 0 && x[xl - 1 + H] == 0 { - set_len(x, xl - 1); - } - - return c; -} - - -// Returns z = (x * y) div B, c = (x * y) mod B. -func umul1(x, y Word) (z Word, c Word) { - const L2 = (L + 1) >> 1; - const B2 = 1 << L2; - const M2 = B2 - 1; - - x0 := x & M2; - x1 := x >> L2; - - y0 := y & M2; - y1 := y >> L2; - - z10 := x0*y0; - z21 := x1*y0 + x0*y1 + (z10 >> L2); - - cc := x1*y1 + (z21 >> L2); - zz := ((z21 & M2) << L2) | (z10 & M2); - return zz, cc -} - - -func umul(x Value, y Value) Value { - if zero(x) || zero(y) { - return make(0); - } - xl := len_(x); - yl := len_(y); - if xl < yl { - return umul(y, x); // for speed - } - ASSERT(xl >= yl && yl > 0); - - // initialize z - zl := xl + yl; - z := alloc(zl); - for i := 0; i < zl; i++ { z[i + H] = 0; } - - k := 0; - for j := 0; j < yl; j++ { - d := y[j + H]; - if d != 0 { - k = j; - c := Word(0); - for i := 0; i < xl; i++ { - // compute z[k + H] += x[i + H] * d + c; - t := z[k + H] + c; - var z1 Word; - z1, c = umul1(x[i + H], d); - t += z1; - z[k + H] = t & M; - c += t >> L; - k++; - } - if c != 0 { - z[k + H] = Word(c); - k++; - } - } - } - set_len(z, k); - - return z; -} - - -func ucmp(x Value, y Value) int { - xl := len_(x); - yl := len_(y); - - if xl != yl || xl == 0 { - return xl - yl; - } - - i := xl - 1; - for i > 0 && x[i + H] == y[i + H] { i--; } - return int(x[i + H]) - int(y[i + H]); -} - - -func ulog(x Value) int { - xl := len_(x); - if xl == 0 { return 0; } - - n := (xl - 1) * L; - for t := x[xl - 1 + H]; t != 0; t >>= 1 { n++ }; - - return n; -} - - -func make(x int) Value { - if x == 0 { - z := alloc(0); - set_len(z, 0); - return z; - } - - if x == -x { // smallest int - z := alloc(2); - z[0 + H] = 0; - z[1 + H] = 1; - set_len(z, -2); - return z; - } - - z := alloc(1); - if x < 0 { - z[0 + H] = Word(-x); - set_len(z, -1); - } else { - z[0 + H] = Word(x); - set_len(z, 1); - } - - return z; -} - - -func make_from_string(s string) Value { - // skip sign, if any - i := 0; - if len(s) > 0 && (s[i] == '-' || s[i] == '+') { - i = 1; - } - - // read digits - x := make(0); - for i < len(s) && '0' <= s[i] && s[i] <= '9' { - x = umul_add(x, 10, Word(s[i] - '0')); - i++; - } - - // read sign - if len(s) > 0 && s[0] == '-' { - neg(x); - } - - return x; -} - - -// ---------------------------------------------------------------------------- -// Creation - - -func (x Integer) Init(val Value) Integer { - x.val = val; - return x; -} - - -// ---------------------------------------------------------------------------- -// Signed ops - -func add(x Value, y Value) Value { - var z Value; - if sign(x) == sign(y) { - // x + y == x + y - // (-x) + (-y) == -(x + y) - z = uadd(x, y); - } else { - // x + (-y) == x - y == -(y - x) - // (-x) + y == y - x == -(x - y) - if ucmp(x, y) >= 0 { - z = usub(x, y); - } else { - z = usub(y, x); - neg(z); - } - } - if sign(x) { - neg(z); - } - return z; -} - - -func sub(x Value, y Value) Value { - var z Value; - if sign(x) != sign(y) { - // x - (-y) == x + y - // (-x) - y == -(x + y) - z = uadd(x, y); - } else { - // x - y == x - y == -(y - x) - // (-x) - (-y) == y - x == -(x - y) - if ucmp(x, y) >= 0 { - z = usub(x, y); - } else { - z = usub(y, x); - neg(z); - } - } - if sign(x) { - neg(z); - } - return z; -} - - -func mul(x Value, y Value) Value { - // x * y == x * y - // x * (-y) == -(x * y) - // (-x) * y == -(x * y) - // (-x) * (-y) == x * y - z := umul(x, y); - if sign(x) != sign(y) { - neg(z); - } - return z; -} - - -func mul_range(a, b int) Value { - if a > b { return make(1) }; - if a == b { return make(a) }; - if a + 1 == b { return mul(make(a), make(b)) }; - m := (a + b) >> 1; - ASSERT(a <= m && m < b); - return mul(mul_range(a, m), mul_range(m + 1, b)); -} - - -func fact(n int) Value { - return mul_range(2, n); -} - - -// Returns a copy of x with space for one extra digit. -func copy(x Value) Value { - xl := len_(x); - - z := alloc(xl + 1); // add space for one extra digit - for i := 0; i < xl; i++ { z[i + H] = x[i + H]; } - set_len(z, int(x[0])); // don't loose sign! - - return z; -} - - -func tostring(x Value) string { - // allocate string - // approx. length: 1 char for 3 bits - n := ulog(x)/3 + 3; // +1 (round up) +1 (sign) +1 (0 termination) - //s := new([]byte, n); - s := new([100000]byte); - - // convert - z := copy(x); - i := 0; - for i == 0 || !zero(z) { - s[i] = byte(umod(z, 10) + '0'); - i++; - }; - if sign(x) { - s[i] = '-'; - i++; - } - length := i; - ASSERT(0 < i && i < n); - - // reverse in place - i--; - for j := 0; j < i; j++ { - t := s[j]; - s[j] = s[i]; - s[i] = t; - i--; - } - - return string(s)[0:length]; -} - - -// ---------------------------------------------------------------------------- -// Creation - -export func FromInt(v int) Integer { - return new(IntegerImpl).Init(make(v)); -} - - -export func FromString(s string) Integer { - return new(IntegerImpl).Init(make_from_string(s)); -} - - -// ---------------------------------------------------------------------------- -// Arithmetic ops - -func (x Integer) neg () Integer { - if (zero(x.val)) { - return new(IntegerImpl).Init(make(0)); - } - - z := copy(x.val); - neg(z); - return new(IntegerImpl).Init(z); -} - - -func (x Integer) add (y Integer) Integer { - return new(IntegerImpl).Init(add(x.val, y.val)); -} - - -func (x Integer) sub (y Integer) Integer { - return new(IntegerImpl).Init(sub(x.val, y.val)); -} - - -func (x Integer) mul (y Integer) Integer { - return new(IntegerImpl).Init(mul(x.val, y.val)); -} - - -func (x Integer) quo (y Integer) Integer { - UNIMPLEMENTED("quo"); - return nil; -} - - -func (x Integer) rem (y Integer) Integer { - UNIMPLEMENTED("rem"); - return nil; -} - - -func (x Integer) div (y Integer) Integer { - UNIMPLEMENTED("div"); - return nil; -} - - -func (x Integer) mod (y Integer) Integer { - UNIMPLEMENTED("mod"); - return nil; -} - - -// ---------------------------------------------------------------------------- -// Arithmetic shifts - -func (x Integer) shl (s uint) Integer { - UNIMPLEMENTED("shl"); - return nil; -} - - -func (x Integer) shr (s uint) Integer { - UNIMPLEMENTED("shr"); - return nil; -} - - -// ---------------------------------------------------------------------------- -// Logical ops - -func (x Integer) inv () Integer { - UNIMPLEMENTED("inv"); - return nil; -} - - -func (x Integer) and (y Integer) Integer { - UNIMPLEMENTED("and"); - return nil; -} - - -func (x Integer) or (y Integer) Integer { - UNIMPLEMENTED("or"); - return nil; -} - - -func (x Integer) xor (y Integer) Integer { - UNIMPLEMENTED("xor"); - return nil; -} - - -// ---------------------------------------------------------------------------- -// Comparisons - -func (x Integer) cmp (y Integer) int { - // do better then this - d := x.sub(y); - switch { - case sign(d.val): return -1; - case zero(d.val): return 0; - default : return +1; - } - panic("UNREACHABLE"); -} - - -func (x Integer) eql (y Integer) bool { - return x.cmp(y) == 0; -} - - -func (x Integer) neq (y Integer) bool { - return x.cmp(y) != 0; -} - - -func (x Integer) lss (y Integer) bool { - return x.cmp(y) < 0; -} - - -func (x Integer) leq (y Integer) bool { - return x.cmp(y) <= 0; -} - - -func (x Integer) gtr (y Integer) bool { - return x.cmp(y) > 0; -} - - -func (x Integer) geq (y Integer) bool { - return x.cmp(y) >= 0; -} - - -// ---------------------------------------------------------------------------- -// Specials - -export func Fact(n int) Integer { - return new(IntegerImpl).Init(fact(n)); -} - - -func (x Integer) ToString() string { - return tostring(x.val); -} - - -func (x Integer) ToInt() int { - v := x.val; - if len_(v) <= 1 { - if zero(v) { - return 0; - } - i := int(v[0 + H]); - if sign(v) { - i = -i; // incorrect for smallest int - } - return i; - } - panic("integer too large"); -} diff --git a/usr/gri/bignum/make.bash b/usr/gri/bignum/make.bash deleted file mode 100644 index 3efc5a86c9..0000000000 --- a/usr/gri/bignum/make.bash +++ /dev/null @@ -1,16 +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. - -#!/bin/bash - -set -e - -# clean -rm -f *.6 6.out test_integer - -# integer package -6g integer.go -6g test_integer.go -6l -o test_integer integer.6 test_integer.6 -./test_integer diff --git a/usr/gri/bignum/test_integer.go b/usr/gri/bignum/test_integer.go deleted file mode 100644 index 991c99811c..0000000000 --- a/usr/gri/bignum/test_integer.go +++ /dev/null @@ -1,137 +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. - -package main - -import Integer "integer" - -type Int Integer.Integer; - -const ( - sa = "991"; - sb = "2432902008176640000"; // 20! - sc = "93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000"; // 100! -) - -var ( - m, z, p, - a, b, c, - a_a, a_b, a_c, b_b, b_c, c_c, a_b_c - Int -) - - -func CHECK(msg string, p bool) { - if !p { - panic("CHECK failed: ", msg, "\n"); - } -} - - -func Init() { - m = Integer.FromInt(-1); - z = Integer.FromInt(0); - p = Integer.FromInt(1); - - a = Integer.FromString(sa); - b = Integer.FromString(sb); - c = Integer.FromString(sc); - - a_a = Integer.FromInt(991 + 991); - a_b = Integer.FromString("2432902008176640991"); - a_c = Integer.FromString("93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000991"); -} - -func N991() string { return "991" } - -func TestConv() { - print("TestConv\n"); - CHECK("TC1", a.eql(Integer.FromInt(991))); - CHECK("TC2", b.eql(Integer.Fact(20))); - CHECK("TC3", c.eql(Integer.Fact(100))); - CHECK("TC4", a.ToString() == sa); - CHECK("TC5", b.ToString() == sb); - CHECK("TC6", c.ToString() == sc); - - // also tested much via TestFact -} - - -func TestAdd() { - print("TestAdd\n"); - CHECK("TA1", z.add(z).eql(z)); - CHECK("TA2", a.add(z).eql(a)); - CHECK("TA3", z.add(a).eql(a)); - - CHECK("TA4", c.add(z).eql(c)); - CHECK("TA5", z.add(c).eql(c)); - - CHECK("TA6", m.add(p).eql(z)); - - CHECK("TA7", a.add(a).eql(a_a)); - CHECK("TA8", a.add(b).eql(a_b)); - CHECK("TA9", a.add(c).eql(a_c)); - - // needs more -} - - -func TestSub() { - print("TestSub\n"); - CHECK("TS1", z.sub(z).eql(z)); - CHECK("TS2", a.sub(z).eql(a)); - CHECK("TS3", z.sub(a).eql(a.neg())); - - CHECK("TS4", c.sub(z).eql(c)); - CHECK("TS5", z.sub(c).eql(c.neg())); - - CHECK("TS6", p.sub(m).eql(p.add(p))); - - CHECK("TS7", a.sub(a).eql(z)); - - // needs more -} - - -func TestMul() { - print("TestMul\n"); - // tested much via TestFact for now -} - - -func TestDiv() { - print("TestDiv\n"); - // no div implemented yet -} - - -func TestMod() { - print("TestMod\n"); - // no mod implemented yet -} - - -func TestFact() { - print("TestFact\n"); - for n := 990; n < 1010; n++ { - f := Integer.Fact(n); - CHECK("TF", Integer.FromString(f.ToString()).eql(f)); - } -} - - -func main() { - Init(); - - TestConv(); - TestAdd(); - TestSub(); - TestMul(); - TestDiv(); - TestMod(); - - TestFact(); - - print("PASSED\n"); -}