diff options
Diffstat (limited to 'src/pkg/bignum')
-rw-r--r-- | src/pkg/bignum/arith.go | 26 | ||||
-rwxr-xr-x | src/pkg/bignum/bignum.go | 218 | ||||
-rw-r--r-- | src/pkg/bignum/bignum_test.go | 177 | ||||
-rw-r--r-- | src/pkg/bignum/integer.go | 26 | ||||
-rw-r--r-- | src/pkg/bignum/nrdiv_test.go | 18 | ||||
-rw-r--r-- | src/pkg/bignum/rational.go | 14 |
6 files changed, 259 insertions, 220 deletions
diff --git a/src/pkg/bignum/arith.go b/src/pkg/bignum/arith.go index 4ae7e3e0a..f60b66828 100644 --- a/src/pkg/bignum/arith.go +++ b/src/pkg/bignum/arith.go @@ -18,14 +18,14 @@ func Mul128(x, y uint64) (z1, z0 uint64) { // and return the product as 2 words. const ( - W = uint(unsafe.Sizeof(x))*8; - W2 = W/2; - B2 = 1<<W2; - M2 = B2-1; + W = uint(unsafe.Sizeof(x)) * 8; + W2 = W/2; + B2 = 1<<W2; + M2 = B2-1; ) if x < y { - x, y = y, x + x, y = y, x; } if x < B2 { @@ -41,7 +41,7 @@ func Mul128(x, y uint64) (z1, z0 uint64) { // x = (x1*B2 + x0) // y = (y1*B2 + y0) x1, x0 := x>>W2, x&M2; - + // x*y = t2*B2*B2 + t1*B2 + t0 t0 := x0*y; t1 := x1*y; @@ -49,7 +49,7 @@ func Mul128(x, y uint64) (z1, z0 uint64) { // compute result digits but avoid overflow // z = z[1]*B + z[0] = x*y z0 = t1<<W2 + t0; - z1 = (t1 + t0>>W2) >> W2; + z1 = (t1 + t0>>W2)>>W2; return; } @@ -68,7 +68,7 @@ func Mul128(x, y uint64) (z1, z0 uint64) { // compute result digits but avoid overflow // z = z[1]*B + z[0] = x*y z0 = t1<<W2 + t0; - z1 = t2 + (t1 + t0>>W2) >> W2; + z1 = t2 + (t1 + t0>>W2)>>W2; return; } @@ -80,10 +80,10 @@ func MulAdd128(x, y, c uint64) (z1, z0 uint64) { // and return the product as 2 words. const ( - W = uint(unsafe.Sizeof(x))*8; - W2 = W/2; - B2 = 1<<W2; - M2 = B2-1; + W = uint(unsafe.Sizeof(x)) * 8; + W2 = W/2; + B2 = 1<<W2; + M2 = B2-1; ) // TODO(gri) Should implement special cases for faster execution. @@ -104,7 +104,7 @@ func MulAdd128(x, y, c uint64) (z1, z0 uint64) { // compute result digits but avoid overflow // z = z[1]*B + z[0] = x*y z0 = t1<<W2 + t0; - z1 = t2 + (t1 + t0>>W2) >> W2; + z1 = t2 + (t1 + t0>>W2)>>W2; return; } diff --git a/src/pkg/bignum/bignum.go b/src/pkg/bignum/bignum.go index 2fc138cda..55bdad0ab 100755 --- a/src/pkg/bignum/bignum.go +++ b/src/pkg/bignum/bignum.go @@ -56,25 +56,25 @@ import ( // in bits must be even. type ( - digit uint64; - digit2 uint32; // half-digits for division + digit uint64; + digit2 uint32; // half-digits for division ) const ( - logW = 64; // word width - logH = 4; // bits for a hex digit (= small number) - logB = logW - logH; // largest bit-width available + logW = 64; // word width + logH = 4; // bits for a hex digit (= small number) + logB = logW-logH; // largest bit-width available // half-digits - _W2 = logB / 2; // width - _B2 = 1 << _W2; // base - _M2 = _B2 - 1; // mask + _W2 = logB/2; // width + _B2 = 1<<_W2; // base + _M2 = _B2-1; // mask // full digits - _W = _W2 * 2; // width - _B = 1 << _W; // base - _M = _B - 1; // mask + _W = _W2*2; // width + _B = 1<<_W; // base + _M = _B-1; // mask ) @@ -110,14 +110,14 @@ func dump(x Natural) { // Natural represents an unsigned integer value of arbitrary precision. // -type Natural []digit; +type Natural []digit // Nat creates a small natural number with value x. // func Nat(x uint64) Natural { if x == 0 { - return nil; // len == 0 + return nil; // len == 0 } // single-digit values @@ -138,7 +138,7 @@ func Nat(x uint64) Natural { // split x into digits z := make(Natural, n); for i := 0; i < n; i++ { - z[i] = digit(x & _M); + z[i] = digit(x&_M); x >>= _W; } @@ -152,8 +152,10 @@ func (x Natural) Value() uint64 { // single-digit values n := len(x); switch n { - case 0: return 0; - case 1: return uint64(x[0]); + case 0: + return 0; + case 1: + return uint64(x[0]); } // multi-digit values @@ -162,7 +164,7 @@ func (x Natural) Value() uint64 { z := uint64(0); s := uint(0); for i := 0; i < n && s < 64; i++ { - z += uint64(x[i]) << s; + z += uint64(x[i])<<s; s += _W; } @@ -204,8 +206,10 @@ func (x Natural) IsZero() bool { func normalize(x Natural) Natural { n := len(x); - for n > 0 && x[n-1] == 0 { n-- } - return x[0 : n]; + for n > 0 && x[n-1] == 0 { + n--; + } + return x[0:n]; } @@ -219,7 +223,7 @@ func nalloc(z Natural, n int) Natural { size = 4; } if size <= cap(z) { - return z[0 : n]; + return z[0:n]; } return make(Natural, n, size); } @@ -240,12 +244,12 @@ func Nadd(zp *Natural, x, y Natural) { c := digit(0); i := 0; for i < m { - t := c + x[i] + y[i]; + t := c+x[i]+y[i]; c, z[i] = t>>_W, t&_M; i++; } for i < n { - t := c + x[i]; + t := c+x[i]; c, z[i] = t>>_W, t&_M; i++; } @@ -253,7 +257,7 @@ func Nadd(zp *Natural, x, y Natural) { z[i] = c; i++; } - *zp = z[0 : i] + *zp = z[0:i]; } @@ -274,20 +278,20 @@ func Nsub(zp *Natural, x, y Natural) { n := len(x); m := len(y); if n < m { - panic("underflow") + panic("underflow"); } z := nalloc(*zp, n); c := digit(0); i := 0; for i < m { - t := c + x[i] - y[i]; - c, z[i] = digit(int64(t)>>_W), t&_M; // requires arithmetic shift! + t := c+x[i]-y[i]; + c, z[i] = digit(int64(t)>>_W), t&_M; // requires arithmetic shift! i++; } for i < n { - t := c + x[i]; - c, z[i] = digit(int64(t)>>_W), t&_M; // requires arithmetic shift! + t := c+x[i]; + c, z[i] = digit(int64(t)>>_W), t&_M; // requires arithmetic shift! i++; } if int64(c) < 0 { @@ -311,7 +315,7 @@ func (x Natural) Sub(y Natural) Natural { // func muladd11(x, y, c digit) (digit, digit) { z1, z0 := MulAdd128(uint64(x), uint64(y), uint64(c)); - return digit(z1<<(64 - logB) | z0>>logB), digit(z0&_M); + return digit(z1<<(64-logB) | z0>>logB), digit(z0&_M); } @@ -329,7 +333,7 @@ func Nscale(z *Natural, d uint64) { switch { case d == 0: *z = Nat(0); - return + return; case d == 1: return; case d >= _B: @@ -346,7 +350,7 @@ func Nscale(z *Natural, d uint64) { for i, d := range *z { zz[i] = d; } - *z = zz + *z = zz; } else { *z = (*z)[0 : n+1]; } @@ -360,7 +364,7 @@ func Nscale(z *Natural, d uint64) { func muladd1(x Natural, d, c digit) Natural { assert(isSmall(d-1) && isSmall(c)); n := len(x); - z := make(Natural, n + 1); + z := make(Natural, n+1); for i := 0; i < n; i++ { t := c + x[i]*d; @@ -376,13 +380,17 @@ func muladd1(x Natural, d, c digit) Natural { // func (x Natural) Mul1(d uint64) Natural { switch { - case d == 0: return Nat(0); - case d == 1: return x; - case isSmall(digit(d)): muladd1(x, digit(d), 0); - case d >= _B: return x.Mul(Nat(d)); + case d == 0: + return Nat(0); + case d == 1: + return x; + case isSmall(digit(d)): + muladd1(x, digit(d), 0); + case d >= _B: + return x.Mul(Nat(d)); } - z := make(Natural, len(x) + 1); + z := make(Natural, len(x)+1); c := mul1(z, x, digit(d)); z[len(x)] = c; return normalize(z); @@ -406,13 +414,13 @@ func (x Natural) Mul(y Natural) Natural { return x.Mul1(uint64(y[0])); } - z := make(Natural, n + m); + z := make(Natural, n+m); for j := 0; j < m; j++ { d := y[j]; if d != 0 { c := digit(0); for i := 0; i < n; i++ { - c, z[i+j] = muladd11(x[i], d, z[i+j] + c); + c, z[i+j] = muladd11(x[i], d, z[i+j]+c); } z[n+j] = c; } @@ -429,30 +437,32 @@ func (x Natural) Mul(y Natural) Natural { func unpack(x Natural) []digit2 { n := len(x); - z := make([]digit2, n*2 + 1); // add space for extra digit (used by DivMod) + z := make([]digit2, n*2 + 1); // add space for extra digit (used by DivMod) for i := 0; i < n; i++ { t := x[i]; - z[i*2] = digit2(t & _M2); - z[i*2 + 1] = digit2(t >> _W2 & _M2); + z[i*2] = digit2(t&_M2); + z[i*2 + 1] = digit2(t>>_W2&_M2); } // normalize result k := 2*n; - for k > 0 && z[k - 1] == 0 { k-- } - return z[0 : k]; // trim leading 0's + for k > 0 && z[k-1] == 0 { + k--; + } + return z[0:k]; // trim leading 0's } func pack(x []digit2) Natural { - n := (len(x) + 1) / 2; + n := (len(x)+1)/2; z := make(Natural, n); - if len(x) & 1 == 1 { + if len(x)&1 == 1 { // handle odd len(x) n--; z[n] = digit(x[n*2]); } for i := 0; i < n; i++ { - z[i] = digit(x[i*2 + 1]) << _W2 | digit(x[i*2]); + z[i] = digit(x[i*2 + 1])<<_W2 | digit(x[i*2]); } return normalize(z); } @@ -506,14 +516,14 @@ func divmod(x, y []digit2) ([]digit2, []digit2) { if m == 0 { panic("division by zero"); } - assert(n+1 <= cap(x)); // space for one extra digit + assert(n+1 <= cap(x)); // space for one extra digit x = x[0 : n+1]; assert(x[n] == 0); if m == 1 { // division by single digit // result is shifted left by 1 in place! - x[0] = div21(x[1 : n+1], x[0 : n], y[0]); + x[0] = div21(x[1 : n+1], x[0:n], y[0]); } else if m > n { // y > x => quotient = 0, remainder = x @@ -528,12 +538,12 @@ func divmod(x, y []digit2) ([]digit2, []digit2) { // TODO Instead of multiplying, it would be sufficient to // shift y such that the normalization condition is // satisfied (as done in Hacker's Delight). - f := _B2 / (digit(y[m-1]) + 1); + f := _B2/(digit(y[m-1])+1); if f != 1 { mul21(x, x, digit2(f)); mul21(y, y, digit2(f)); } - assert(_B2/2 <= y[m-1] && y[m-1] < _B2); // incorrect scaling + assert(_B2/2 <= y[m-1] && y[m-1] < _B2); // incorrect scaling y1, y2 := digit(y[m-1]), digit(y[m-2]); for i := n-m; i >= 0; i-- { @@ -541,14 +551,15 @@ func divmod(x, y []digit2) ([]digit2, []digit2) { // compute trial digit (Knuth) var q digit; - { x0, x1, x2 := digit(x[k]), digit(x[k-1]), digit(x[k-2]); + { + x0, x1, x2 := digit(x[k]), digit(x[k-1]), digit(x[k-2]); if x0 != y1 { q = (x0<<_W2 + x1)/y1; } else { q = _B2-1; } for y2*q > (x0<<_W2 + x1 - y1*q)<<_W2 + x2 { - q-- + q--; } } @@ -556,18 +567,18 @@ func divmod(x, y []digit2) ([]digit2, []digit2) { c := digit(0); for j := 0; j < m; j++ { t := c + digit(x[i+j]) - digit(y[j])*q; - c, x[i+j] = digit(int64(t) >> _W2), digit2(t & _M2); // requires arithmetic shift! + c, x[i+j] = digit(int64(t)>>_W2), digit2(t&_M2); // requires arithmetic shift! } // correct if trial digit was too large - if c + digit(x[k]) != 0 { + if c+digit(x[k]) != 0 { // add y c := digit(0); for j := 0; j < m; j++ { - t := c + digit(x[i+j]) + digit(y[j]); - c, x[i+j] = t >> _W2, digit2(t & _M2) + t := c+digit(x[i+j])+digit(y[j]); + c, x[i+j] = t>>_W2, digit2(t&_M2); } - assert(c + digit(x[k]) == 0); + assert(c+digit(x[k]) == 0); // correct trial digit q--; } @@ -577,12 +588,12 @@ func divmod(x, y []digit2) ([]digit2, []digit2) { // undo normalization for remainder if f != 1 { - c := div21(x[0 : m], x[0 : m], digit2(f)); + c := div21(x[0:m], x[0:m], digit2(f)); assert(c == 0); } } - return x[m : n+1], x[0 : m]; + return x[m : n+1], x[0:m]; } @@ -620,7 +631,7 @@ func shl(z, x Natural, s uint) digit { n := len(x); c := digit(0); for i := 0; i < n; i++ { - c, z[i] = x[i] >> (_W-s), x[i] << s & _M | c; + c, z[i] = x[i]>>(_W-s), x[i]<<s&_M | c; } return c; } @@ -643,8 +654,8 @@ func shr(z, x Natural, s uint) digit { assert(s <= _W); n := len(x); c := digit(0); - for i := n - 1; i >= 0; i-- { - c, z[i] = x[i] << (_W-s) & _M, x[i] >> s | c; + for i := n-1; i >= 0; i-- { + c, z[i] = x[i]<<(_W-s)&_M, x[i]>>s | c; } return c; } @@ -655,7 +666,7 @@ func shr(z, x Natural, s uint) digit { func (x Natural) Shr(s uint) Natural { n := uint(len(x)); m := n - s/_W; - if m > n { // check for underflow + if m > n { // check for underflow m = 0; } z := make(Natural, m); @@ -677,7 +688,7 @@ func (x Natural) And(y Natural) Natural { z := make(Natural, m); for i := 0; i < m; i++ { - z[i] = x[i] & y[i]; + z[i] = x[i]&y[i]; } // upper bits are 0 @@ -687,7 +698,7 @@ func (x Natural) And(y Natural) Natural { func copy(z, x Natural) { for i, e := range x { - z[i] = e + z[i] = e; } } @@ -703,9 +714,9 @@ func (x Natural) AndNot(y Natural) Natural { z := make(Natural, n); for i := 0; i < m; i++ { - z[i] = x[i] &^ y[i]; + z[i] = x[i]&^y[i]; } - copy(z[m : n], x[m : n]); + copy(z[m:n], x[m:n]); return normalize(z); } @@ -722,9 +733,9 @@ func (x Natural) Or(y Natural) Natural { z := make(Natural, n); for i := 0; i < m; i++ { - z[i] = x[i] | y[i]; + z[i] = x[i]|y[i]; } - copy(z[m : n], x[m : n]); + copy(z[m:n], x[m:n]); return z; } @@ -741,9 +752,9 @@ func (x Natural) Xor(y Natural) Natural { z := make(Natural, n); for i := 0; i < m; i++ { - z[i] = x[i] ^ y[i]; + z[i] = x[i]^y[i]; } - copy(z[m : n], x[m : n]); + copy(z[m:n], x[m:n]); return normalize(z); } @@ -760,16 +771,20 @@ func (x Natural) Cmp(y Natural) int { m := len(y); if n != m || n == 0 { - return n - m; + return n-m; } - i := n - 1; - for i > 0 && x[i] == y[i] { i--; } + i := n-1; + for i > 0 && x[i] == y[i] { + i--; + } d := 0; switch { - case x[i] < y[i]: d = -1; - case x[i] > y[i]: d = 1; + case x[i] < y[i]: + d = -1; + case x[i] > y[i]: + d = 1; } return d; @@ -787,7 +802,7 @@ func log2(x uint64) uint { x >>= 1; n++; } - return n - 1; + return n-1; } @@ -798,7 +813,7 @@ func log2(x uint64) uint { func (x Natural) Log2() uint { n := len(x); if n > 0 { - return (uint(n) - 1)*_W + log2(uint64(x[n - 1])); + return (uint(n)-1)*_W + log2(uint64(x[n-1])); } panic("Log2(0)"); } @@ -808,10 +823,10 @@ func (x Natural) Log2() uint { // Returns updated x and x mod d. // func divmod1(x Natural, d digit) (Natural, digit) { - assert(0 < d && isSmall(d - 1)); + assert(0 < d && isSmall(d-1)); c := digit(0); - for i := len(x) - 1; i >= 0; i-- { + for i := len(x)-1; i >= 0; i-- { t := c<<_W + x[i]; c, x[i] = t%d, t/d; } @@ -829,7 +844,7 @@ func (x Natural) ToString(base uint) string { // allocate buffer for conversion assert(2 <= base && base <= 16); - n := (x.Log2() + 1) / log2(uint64(base)) + 1; // +1: round up + n := (x.Log2() + 1)/log2(uint64(base)) + 1; // +1: round up s := make([]byte, n); // don't destroy x @@ -843,9 +858,9 @@ func (x Natural) ToString(base uint) string { var d digit; t, d = divmod1(t, digit(base)); s[i] = "0123456789abcdef"[d]; - }; + } - return string(s[i : n]); + return string(s[i:n]); } @@ -859,9 +874,12 @@ func (x Natural) String() string { func fmtbase(c int) uint { switch c { - case 'b': return 2; - case 'o': return 8; - case 'x': return 16; + case 'b': + return 2; + case 'o': + return 8; + case 'x': + return 16; } return 10; } @@ -876,11 +894,14 @@ func (x Natural) Format(h fmt.State, c int) { func hexvalue(ch byte) uint { - d := uint(1 << logH); + d := uint(1<<logH); switch { - case '0' <= ch && ch <= '9': d = uint(ch - '0'); - case 'a' <= ch && ch <= 'f': d = uint(ch - 'a') + 10; - case 'A' <= ch && ch <= 'F': d = uint(ch - 'A') + 10; + case '0' <= ch && ch <= '9': + d = uint(ch-'0'); + case 'a' <= ch && ch <= 'f': + d = uint(ch-'a') + 10; + case 'A' <= ch && ch <= 'F': + d = uint(ch-'A') + 10; } return d; } @@ -942,7 +963,7 @@ func pop1(x digit) uint { // func (x Natural) Pop() uint { n := uint(0); - for i := len(x) - 1; i >= 0; i-- { + for i := len(x)-1; i >= 0; i-- { n += pop1(x[i]); } return n; @@ -970,13 +991,16 @@ func (xp Natural) Pow(n uint) Natural { // func MulRange(a, b uint) Natural { switch { - case a > b: return Nat(1); - case a == b: return Nat(uint64(a)); - case a + 1 == b: return Nat(uint64(a)).Mul(Nat(uint64(b))); + case a > b: + return Nat(1); + case a == b: + return Nat(uint64(a)); + case a+1 == b: + return Nat(uint64(a)).Mul(Nat(uint64(b))); } - m := (a + b)>>1; + m := (a+b)>>1; assert(a <= m && m < b); - return MulRange(a, m).Mul(MulRange(m + 1, b)); + return MulRange(a, m).Mul(MulRange(m+1, b)); } diff --git a/src/pkg/bignum/bignum_test.go b/src/pkg/bignum/bignum_test.go index 2b2be6693..230e42f13 100644 --- a/src/pkg/bignum/bignum_test.go +++ b/src/pkg/bignum/bignum_test.go @@ -10,12 +10,12 @@ import ( ) const ( - sa = "991"; - sb = "2432902008176640000"; // 20! - sc = "933262154439441526816992388562667004907159682643816214685929" - "638952175999932299156089414639761565182862536979208272237582" - "51185210916864000000000000000000000000"; // 100! - sp = "170141183460469231731687303715884105727"; // prime + sa = "991"; + sb = "2432902008176640000"; // 20! + sc = "933262154439441526816992388562667004907159682643816214685929" + "638952175999932299156089414639761565182862536979208272237582" + "51185210916864000000000000000000000000"; // 100! + sp = "170141183460469231731687303715884105727"; // prime ) func natFromString(s string, base uint, slen *int) Natural { @@ -46,30 +46,26 @@ func ratFromString(s string, base uint, slen *int) *Rational { var ( - nat_zero = Nat(0); - nat_one = Nat(1); - nat_two = Nat(2); - - a = natFromString(sa, 10, nil); - b = natFromString(sb, 10, nil); - c = natFromString(sc, 10, nil); - p = natFromString(sp, 10, nil); - - int_zero = Int(0); - int_one = Int(1); - int_two = Int(2); - - ip = intFromString(sp, 10, nil); - - rat_zero = Rat(0, 1); - rat_half = Rat(1, 2); - rat_one = Rat(1, 1); - rat_two = Rat(2, 1); + nat_zero = Nat(0); + nat_one = Nat(1); + nat_two = Nat(2); + a = natFromString(sa, 10, nil); + b = natFromString(sb, 10, nil); + c = natFromString(sc, 10, nil); + p = natFromString(sp, 10, nil); + int_zero = Int(0); + int_one = Int(1); + int_two = Int(2); + ip = intFromString(sp, 10, nil); + rat_zero = Rat(0, 1); + rat_half = Rat(1, 2); + rat_one = Rat(1, 1); + rat_two = Rat(2, 1); ) -var test_msg string; -var tester *testing.T; +var test_msg string +var tester *testing.T func test(n uint, b bool) { if !b { @@ -102,7 +98,10 @@ func rat_eq(n uint, x, y *Rational) { func TestNatConv(t *testing.T) { tester = t; test_msg = "NatConvA"; - type entry1 struct { x uint64; s string }; + type entry1 struct { + x uint64; + s string; + } tab := []entry1{ entry1{0, "0"}, entry1{255, "255"}, @@ -111,8 +110,8 @@ func TestNatConv(t *testing.T) { entry1{18446744073709551615, "18446744073709551615"}, }; for i, e := range tab { - test(100 + uint(i), Nat(e.x).String() == e.s); - test(200 + uint(i), natFromString(e.s, 0, nil).Value() == e.x); + test(100+uint(i), Nat(e.x).String() == e.s); + test(200+uint(i), natFromString(e.s, 0, nil).Value() == e.x); } test_msg = "NatConvB"; @@ -168,7 +167,10 @@ func abs(x int64) uint64 { func TestIntConv(t *testing.T) { tester = t; test_msg = "IntConvA"; - type entry2 struct { x int64; s string }; + type entry2 struct { + x int64; + s string; + } tab := []entry2{ entry2{0, "0"}, entry2{-128, "-128"}, @@ -181,9 +183,9 @@ func TestIntConv(t *testing.T) { entry2{9223372036854775807, "9223372036854775807"}, }; for i, e := range tab { - test(100 + uint(i), Int(e.x).String() == e.s); - test(200 + uint(i), intFromString(e.s, 0, nil).Value() == e.x); - test(300 + uint(i), Int(e.x).Abs().Value() == abs(e.x)); + test(100+uint(i), Int(e.x).String() == e.s); + test(200+uint(i), intFromString(e.s, 0, nil).Value() == e.x); + test(300+uint(i), Int(e.x).Abs().Value() == abs(e.x)); } test_msg = "IntConvB"; @@ -335,26 +337,28 @@ func TestNatDiv(t *testing.T) { func TestIntQuoRem(t *testing.T) { tester = t; test_msg = "IntQuoRem"; - type T struct { x, y, q, r int64 }; + type T struct { + x, y, q, r int64; + } a := []T{ T{+8, +3, +2, +2}, T{+8, -3, -2, +2}, T{-8, +3, -2, -2}, T{-8, -3, +2, -2}, - T{+1, +2, 0, +1}, - T{+1, -2, 0, +1}, - T{-1, +2, 0, -1}, - T{-1, -2, 0, -1}, + T{+1, +2, 0, +1}, + T{+1, -2, 0, +1}, + T{-1, +2, 0, -1}, + T{-1, -2, 0, -1}, }; for i := uint(0); i < uint(len(a)); i++ { e := &a[i]; x, y := Int(e.x).Mul(ip), Int(e.y).Mul(ip); q, r := Int(e.q), Int(e.r).Mul(ip); qq, rr := x.QuoRem(y); - int_eq(4*i+0, x.Quo(y), q); - int_eq(4*i+1, x.Rem(y), r); - int_eq(4*i+2, qq, q); - int_eq(4*i+3, rr, r); + int_eq(4*i + 0, x.Quo(y), q); + int_eq(4*i + 1, x.Rem(y), r); + int_eq(4*i + 2, qq, q); + int_eq(4*i + 3, rr, r); } } @@ -362,14 +366,16 @@ func TestIntQuoRem(t *testing.T) { func TestIntDivMod(t *testing.T) { tester = t; test_msg = "IntDivMod"; - type T struct { x, y, q, r int64 }; + type T struct { + x, y, q, r int64; + } a := []T{ T{+8, +3, +2, +2}, T{+8, -3, -2, +2}, T{-8, +3, -3, +1}, T{-8, -3, +3, +1}, - T{+1, +2, 0, +1}, - T{+1, -2, 0, +1}, + T{+1, +2, 0, +1}, + T{+1, -2, 0, +1}, T{-1, +2, -1, +1}, T{-1, -2, +1, +1}, }; @@ -378,10 +384,10 @@ func TestIntDivMod(t *testing.T) { x, y := Int(e.x).Mul(ip), Int(e.y).Mul(ip); q, r := Int(e.q), Int(e.r).Mul(ip); qq, rr := x.DivMod(y); - int_eq(4*i+0, x.Div(y), q); - int_eq(4*i+1, x.Mod(y), r); - int_eq(4*i+2, qq, q); - int_eq(4*i+3, rr, r); + int_eq(4*i + 0, x.Div(y), q); + int_eq(4*i + 1, x.Mod(y), r); + int_eq(4*i + 2, qq, q); + int_eq(4*i + 3, rr, r); } } @@ -418,7 +424,8 @@ func TestNatShift(t *testing.T) { } test_msg = "NatShift3L"; - { const m = 3; + { + const m = 3; p := b; f := Nat(1<<m); for i := uint(0); i < 100; i++ { @@ -428,7 +435,8 @@ func TestNatShift(t *testing.T) { } test_msg = "NatShift3R"; - { p := c; + { + p := c; for i := uint(0); !p.IsZero(); i++ { nat_eq(i, c.Shr(i), p); p = p.Shr(1); @@ -453,7 +461,8 @@ func TestIntShift(t *testing.T) { } test_msg = "IntShift3L"; - { const m = 3; + { + const m = 3; p := ip; f := Int(1<<m); for i := uint(0); i < 100; i++ { @@ -463,7 +472,8 @@ func TestIntShift(t *testing.T) { } test_msg = "IntShift3R"; - { p := ip; + { + p := ip; for i := uint(0); p.IsPos(); i++ { int_eq(i, ip.Shr(i), p); p = p.Shr(1); @@ -487,25 +497,25 @@ func TestNatBitOps(t *testing.T) { by := Nat(y); test_msg = "NatAnd"; - bz := Nat(x & y); + bz := Nat(x&y); for i := uint(0); i < 100; i++ { nat_eq(i, bx.Shl(i).And(by.Shl(i)), bz.Shl(i)); } test_msg = "NatAndNot"; - bz = Nat(x &^ y); + bz = Nat(x&^y); for i := uint(0); i < 100; i++ { nat_eq(i, bx.Shl(i).AndNot(by.Shl(i)), bz.Shl(i)); } test_msg = "NatOr"; - bz = Nat(x | y); + bz = Nat(x|y); for i := uint(0); i < 100; i++ { nat_eq(i, bx.Shl(i).Or(by.Shl(i)), bz.Shl(i)); } test_msg = "NatXor"; - bz = Nat(x ^ y); + bz = Nat(x^y); for i := uint(0); i < 100; i++ { nat_eq(i, bx.Shl(i).Xor(by.Shl(i)), bz.Shl(i)); } @@ -515,19 +525,21 @@ func TestNatBitOps(t *testing.T) { func TestIntBitOps1(t *testing.T) { tester = t; test_msg = "IntBitOps1"; - type T struct { x, y int64 }; - a := []T { - T{ +7, +3 }, - T{ +7, -3 }, - T{ -7, +3 }, - T{ -7, -3 }, + type T struct { + x, y int64; + } + a := []T{ + T{+7, +3}, + T{+7, -3}, + T{-7, +3}, + T{-7, -3}, }; for i := uint(0); i < uint(len(a)); i++ { e := &a[i]; - int_eq(4*i+0, Int(e.x).And(Int(e.y)), Int(e.x & e.y)); - int_eq(4*i+1, Int(e.x).AndNot(Int(e.y)), Int(e.x &^ e.y)); - int_eq(4*i+2, Int(e.x).Or(Int(e.y)), Int(e.x | e.y)); - int_eq(4*i+3, Int(e.x).Xor(Int(e.y)), Int(e.x ^ e.y)); + int_eq(4*i + 0, Int(e.x).And(Int(e.y)), Int(e.x & e.y)); + int_eq(4*i + 1, Int(e.x).AndNot(Int(e.y)), Int(e.x &^ e.y)); + int_eq(4*i + 2, Int(e.x).Or(Int(e.y)), Int(e.x | e.y)); + int_eq(4*i + 3, Int(e.x).Xor(Int(e.y)), Int(e.x ^ e.y)); } } @@ -536,19 +548,19 @@ func TestIntBitOps2(t *testing.T) { tester = t; test_msg = "IntNot"; - int_eq(0, Int(-2).Not(), Int( 1)); - int_eq(0, Int(-1).Not(), Int( 0)); - int_eq(0, Int( 0).Not(), Int(-1)); - int_eq(0, Int( 1).Not(), Int(-2)); - int_eq(0, Int( 2).Not(), Int(-3)); + int_eq(0, Int(-2).Not(), Int(1)); + int_eq(0, Int(-1).Not(), Int(0)); + int_eq(0, Int(0).Not(), Int(-1)); + int_eq(0, Int(1).Not(), Int(-2)); + int_eq(0, Int(2).Not(), Int(-3)); test_msg = "IntAnd"; for x := int64(-15); x < 5; x++ { bx := Int(x); for y := int64(-5); y < 15; y++ { by := Int(y); - for i := uint(50); i < 70; i++ { // shift across 64bit boundary - int_eq(i, bx.Shl(i).And(by.Shl(i)), Int(x & y).Shl(i)); + for i := uint(50); i < 70; i++ { // shift across 64bit boundary + int_eq(i, bx.Shl(i).And(by.Shl(i)), Int(x&y).Shl(i)); } } } @@ -558,9 +570,9 @@ func TestIntBitOps2(t *testing.T) { bx := Int(x); for y := int64(-5); y < 15; y++ { by := Int(y); - for i := uint(50); i < 70; i++ { // shift across 64bit boundary - int_eq(2*i+0, bx.Shl(i).AndNot(by.Shl(i)), Int(x &^ y).Shl(i)); - int_eq(2*i+1, bx.Shl(i).And(by.Shl(i).Not()), Int(x &^ y).Shl(i)); + for i := uint(50); i < 70; i++ { // shift across 64bit boundary + int_eq(2*i + 0, bx.Shl(i).AndNot(by.Shl(i)), Int(x&^y).Shl(i)); + int_eq(2*i + 1, bx.Shl(i).And(by.Shl(i).Not()), Int(x&^y).Shl(i)); } } } @@ -570,8 +582,8 @@ func TestIntBitOps2(t *testing.T) { bx := Int(x); for y := int64(-5); y < 15; y++ { by := Int(y); - for i := uint(50); i < 70; i++ { // shift across 64bit boundary - int_eq(i, bx.Shl(i).Or(by.Shl(i)), Int(x | y).Shl(i)); + for i := uint(50); i < 70; i++ { // shift across 64bit boundary + int_eq(i, bx.Shl(i).Or(by.Shl(i)), Int(x|y).Shl(i)); } } } @@ -581,8 +593,8 @@ func TestIntBitOps2(t *testing.T) { bx := Int(x); for y := int64(-5); y < 15; y++ { by := Int(y); - for i := uint(50); i < 70; i++ { // shift across 64bit boundary - int_eq(i, bx.Shl(i).Xor(by.Shl(i)), Int(x ^ y).Shl(i)); + for i := uint(50); i < 70; i++ { // shift across 64bit boundary + int_eq(i, bx.Shl(i).Xor(by.Shl(i)), Int(x^y).Shl(i)); } } } @@ -651,4 +663,3 @@ func TestNatPop(t *testing.T) { test(i, nat_one.Shl(i).Sub(nat_one).Pop() == i); } } - diff --git a/src/pkg/bignum/integer.go b/src/pkg/bignum/integer.go index 35a95bb3c..0d0d0ed8e 100644 --- a/src/pkg/bignum/integer.go +++ b/src/pkg/bignum/integer.go @@ -18,8 +18,8 @@ import ( // Integer represents a signed integer value of arbitrary precision. // type Integer struct { - sign bool; - mant Natural; + sign bool; + mant Natural; } @@ -29,7 +29,7 @@ type Integer struct { // func MakeInt(sign bool, mant Natural) *Integer { if mant.IsZero() { - sign = false; // normalize + sign = false; // normalize } return &Integer{sign, mant}; } @@ -95,14 +95,14 @@ func (x *Integer) IsZero() bool { // IsNeg returns true iff x < 0. // func (x *Integer) IsNeg() bool { - return x.sign && !x.mant.IsZero() + return x.sign && !x.mant.IsZero(); } // IsPos returns true iff x >= 0. // func (x *Integer) IsPos() bool { - return !x.sign && !x.mant.IsZero() + return !x.sign && !x.mant.IsZero(); } @@ -383,7 +383,7 @@ func (x *Integer) And(y *Integer) *Integer { // x.sign != y.sign if x.sign { - x, y = y, x; // & is symmetric + x, y = y, x; // & is symmetric } // x & (-y) == x & ^(y-1) == x &^ (y-1) @@ -429,7 +429,7 @@ func (x *Integer) Or(y *Integer) *Integer { // x.sign != y.sign if x.sign { - x, y = y, x; // | or symmetric + x, y = y, x; // | or symmetric } // x | (-y) == x | ^(y-1) == ^((y-1) &^ x) == -(^((y-1) &^ x) + 1) @@ -452,7 +452,7 @@ func (x *Integer) Xor(y *Integer) *Integer { // x.sign != y.sign if x.sign { - x, y = y, x; // ^ is symmetric + x, y = y, x; // ^ is symmetric } // x ^ (-y) == x ^ ^(y-1) == ^(x ^ (y-1)) == -((x ^ (y-1)) + 1) @@ -478,8 +478,10 @@ func (x *Integer) Cmp(y *Integer) int { if x.sign { r = -r; } - case x.sign: r = -1; - case y.sign: r = 1; + case x.sign: + r = -1; + case y.sign: + r = 1; } return r; } @@ -532,7 +534,7 @@ func IntFromString(s string, base uint) (*Integer, uint, int) { i0 = 1; } - mant, base, slen := NatFromString(s[i0 : len(s)], base); + mant, base, slen := NatFromString(s[i0:len(s)], base); - return MakeInt(i0 > 0 && s[0] == '-', mant), base, i0 + slen; + return MakeInt(i0 > 0 && s[0] == '-', mant), base, i0+slen; } diff --git a/src/pkg/bignum/nrdiv_test.go b/src/pkg/bignum/nrdiv_test.go index 24cb4d558..6559d62bc 100644 --- a/src/pkg/bignum/nrdiv_test.go +++ b/src/pkg/bignum/nrdiv_test.go @@ -21,8 +21,8 @@ import "testing" // value of an fpNat x is x.m * 2^x.e . // type fpNat struct { - m Natural; - e int; + m Natural; + e int; } @@ -40,7 +40,7 @@ func (x fpNat) sub(y fpNat) fpNat { // mul2 computes x*2. func (x fpNat) mul2() fpNat { - return fpNat{x.m, x.e+1}; + return fpNat{x.m, x.e + 1}; } @@ -55,8 +55,10 @@ func (x fpNat) mul(y fpNat) fpNat { // func (x fpNat) mant() Natural { switch { - case x.e > 0: return x.m.Shl(uint(x.e)); - case x.e < 0: return x.m.Shr(uint(-x.e)); + case x.e > 0: + return x.m.Shl(uint(x.e)); + case x.e < 0: + return x.m.Shr(uint(-x.e)); } return x.m; } @@ -131,9 +133,9 @@ func nrDivEst(x0, y0 Natural) Natural { // reduce mantissa size // TODO: Find smaller bound as it will reduce // computation time massively. - d := int(r.m.Log2()+1) - maxLen; + d := int(r.m.Log2() + 1) - maxLen; if d > 0 { - r = fpNat{r.m.Shr(uint(d)), r.e+d}; + r = fpNat{r.m.Shr(uint(d)), r.e + d}; } } @@ -188,5 +190,5 @@ func TestNRDiv(t *testing.T) { idiv(t, 7484890589595, 7484890589594); div(t, Fact(100), Fact(91)); div(t, Fact(1000), Fact(991)); - //div(t, Fact(10000), Fact(9991)); // takes too long - disabled for now +//div(t, Fact(10000), Fact(9991)); // takes too long - disabled for now } diff --git a/src/pkg/bignum/rational.go b/src/pkg/bignum/rational.go index baa9b4110..5f7423bac 100644 --- a/src/pkg/bignum/rational.go +++ b/src/pkg/bignum/rational.go @@ -12,15 +12,15 @@ import "fmt" // Rational represents a quotient a/b of arbitrary precision. // type Rational struct { - a *Integer; // numerator - b Natural; // denominator + a *Integer; // numerator + b Natural; // denominator } // MakeRat makes a rational number given a numerator a and a denominator b. // func MakeRat(a *Integer, b Natural) *Rational { - f := a.mant.Gcd(b); // f > 0 + f := a.mant.Gcd(b); // f > 0 if f.Cmp(Nat(1)) != 0 { a = MakeInt(a.sign, a.mant.Div(f)); b = b.Div(f); @@ -191,10 +191,10 @@ func RatFromString(s string, base uint) (*Rational, uint, int) { ch := s[alen]; if ch == '/' { alen++; - b, base, blen = NatFromString(s[alen : len(s)], base); + b, base, blen = NatFromString(s[alen:len(s)], base); } else if ch == '.' { alen++; - b, base, blen = NatFromString(s[alen : len(s)], abase); + b, base, blen = NatFromString(s[alen:len(s)], abase); assert(base == abase); f := Nat(uint64(base)).Pow(uint(blen)); a = MakeInt(a.sign, a.mant.Mul(f).Add(b)); @@ -203,12 +203,12 @@ func RatFromString(s string, base uint) (*Rational, uint, int) { } // read exponent, if any - rlen := alen + blen; + rlen := alen+blen; if rlen < len(s) { ch := s[rlen]; if ch == 'e' || ch == 'E' { rlen++; - e, _, elen := IntFromString(s[rlen : len(s)], 10); + e, _, elen := IntFromString(s[rlen:len(s)], 10); rlen += elen; m := Nat(10).Pow(uint(e.mant.Value())); if e.sign { |