From: Robert Griesemer Date: Tue, 28 Oct 2008 00:57:31 +0000 (-0700) Subject: - bug fixes, cleanups X-Git-Tag: weekly.2009-11-06~2878 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=1daad03545d3758ae16c7acf72d1f32af16542a3;p=gostls13.git - bug fixes, cleanups - integer string conversion R=r OCL=17923 CL=17923 --- diff --git a/usr/gri/bignum/bignum.go b/usr/gri/bignum/bignum.go index 58b78777df..598035c14f 100755 --- a/usr/gri/bignum/bignum.go +++ b/usr/gri/bignum/bignum.go @@ -20,7 +20,8 @@ type Word uint32 const N = 4; const L = 28; // = sizeof(Word) * 8 -const M = 1 << L - 1; +const B = 1 << L; +const M = B - 1; // TODO replace this with a Go built-in assert @@ -31,6 +32,11 @@ func ASSERT(p bool) { } +func IsSmall(x Word) bool { + return x < 1 << N; +} + + func Update(x Word) (Word, Word) { return x & M, x >> L; } @@ -88,8 +94,7 @@ func (x *Natural) Sub (y *Natural) *Natural { // Computes x = x*a + c (in place) for "small" a's. func (x* Natural) Mul1Add(a, c Word) *Natural { - ASSERT(0 <= a && a < 1 << N); - ASSERT(0 <= c && c < 1 << N); + ASSERT(IsSmall(a) && IsSmall(c)); if (x.IsZero() || a == 0) && c == 0 { return NatZero; } @@ -118,10 +123,10 @@ func Mul1(x, y Word) (z Word, c Word) { y1 := y >> L2; z10 := x0*y0; - z21 := x1*y0 + x0*y1 + (z10 >> L2); + z21 := x1*y0 + x0*y1 + z10 >> L2; - cc := x1*y1 + (z21 >> L2); - zz := ((z21 & M2) << L2) | (z10 & M2); + cc := x1*y1 + z21 >> L2; + zz := z21 & M2 << L2 | z10 & M2; return zz, cc } @@ -158,7 +163,7 @@ func (x *Natural) Mul (y *Natural) *Natural { k++; } if c != 0 { - z[k] = Word(c); + z[k] = c; k++; } } @@ -235,7 +240,7 @@ func (x *Natural) Or (y *Natural) *Natural { xl := len(x); yl := len(y); if xl < yl { - return y.And(x); + return y.Or(x); } ASSERT(xl >= yl); z := new(Natural, xl); @@ -252,7 +257,7 @@ func (x *Natural) Xor (y *Natural) *Natural { xl := len(x); yl := len(y); if xl < yl { - return y.And(x); + return y.Xor(x); } ASSERT(xl >= yl); z := new(Natural, xl); @@ -279,29 +284,18 @@ func Copy(x *Natural) *Natural { } -// Computes x = x div d (in place) for "small" d's. Returns x mod d. +// Computes x = x div d (in place) for "small" d's. Returns updated x, x mod d. func (x *Natural) Mod1 (d Word) (*Natural, Word) { - ASSERT(0 < d && d < (1 << N)); + ASSERT(IsSmall(d)); xl := len(x); + c := Word(0); - - i := xl; - for i > 0 { - i--; + for i := xl - 1; i >= 0; i-- { c = c << L + x[i]; - - q := c / d; - x[i] = q; - - //x[i] = c / d; // BUG - - c = c % d; + x[i], c = c / d, c %d; } if xl > 0 && x[xl - 1] == 0 { x = x[0 : xl - 1]; - if xl - 1 == 0 && len(x) != 0 { - panic(); - } } return x, c; @@ -337,7 +331,7 @@ export func NatFromWord(x Word) *Natural { switch { case x == 0: z = NatZero; - case x < 2 << L: + case x < B: z = new(Natural, 1); z[0] = x; return z; @@ -456,6 +450,20 @@ func (x *Integer) Cmp (y *Integer) int { } +func (x *Integer) String() string { + if x.mant.IsZero() { + return "0"; + } + var s string; + if x.sign { + s = "-" + x.mant.String(); + } else { + s = x.mant.String(); + } + return s; +} + + export func IntFromString(s string) *Integer { // get sign, if any sign := false;