big: Add Lsh and Value; convert pidigits to use big

This yields a pretty significant performance boost to pidigits and there are still some improvements to be made. Here are my numbers:

amd64 w/ bignum:
pidigits 10000
        gcc -O2 pidigits.c -lgmp        2.10u 0.00s 2.10r
        gc pidigits     22.92u 0.02s 22.97r
        gc_B pidigits   22.62u 0.00s 22.65r

amd64 w/ big:
pidigits 10000
        gcc -O2 pidigits.c -lgmp        2.09u 0.02s 2.11r
        gc pidigits     12.68u 0.04s 12.72r
        gc_B pidigits   12.71u 0.03s 12.75r

386 w/ bignum:
pidigits 10000
        gcc -O2 pidigits.c -lgmp        2.09u 0.00s 2.09r
        gc pidigits     44.30u 0.01s 44.35r
        gc_B pidigits   44.29u 0.03s 44.35r

386 w/ big:
pidigits 10000
        gcc -O2 pidigits.c -lgmp        2.10u 0.00s 2.10r
        gc pidigits     22.70u 0.06s 22.79r
        gc_B pidigits   22.80u 0.09s 22.91r

R=rsc, gri
CC=golang-dev
https://golang.org/cl/881050
diff --git a/src/pkg/big/int_test.go b/src/pkg/big/int_test.go
index 70dbe59..1e9c0e0 100644
--- a/src/pkg/big/int_test.go
+++ b/src/pkg/big/int_test.go
@@ -192,7 +192,8 @@
 	for i, test := range divSignsTests {
 		x := new(Int).New(test.x)
 		y := new(Int).New(test.y)
-		q, r := new(Int).Div(x, y)
+		r := new(Int)
+		q, r := new(Int).DivMod(x, y, r)
 		expectedQ := new(Int).New(test.q)
 		expectedR := new(Int).New(test.r)
 
@@ -249,7 +250,8 @@
 		return true
 	}
 
-	q, r := new(Int).Div(u, v)
+	r := new(Int)
+	q, r := new(Int).DivMod(u, v, r)
 
 	if r.Cmp(v) >= 0 {
 		return false
@@ -297,7 +299,8 @@
 		expectedQ, _ := new(Int).SetString(test.q, 10)
 		expectedR, _ := new(Int).SetString(test.r, 10)
 
-		q, r := new(Int).Div(x, y)
+		r := new(Int)
+		q, r := new(Int).DivMod(x, y, r)
 
 		if q.Cmp(expectedQ) != 0 || r.Cmp(expectedR) != 0 {
 			t.Errorf("#%d got (%s, %s) want (%s, %s)", i, q, r, expectedQ, expectedR)
@@ -313,7 +316,8 @@
 	u := &Int{false, []Word{0, 0, 1 + 1<<(_W-1), _M ^ (1 << (_W - 1))}}
 	v := &Int{false, []Word{5, 2 + 1<<(_W-1), 1 << (_W - 1)}}
 
-	q, r := new(Int).Div(u, v)
+	r := new(Int)
+	q, r := new(Int).DivMod(u, v, r)
 	const expectedQ64 = "18446744073709551613"
 	const expectedR64 = "3138550867693340382088035895064302439801311770021610913807"
 	const expectedQ32 = "4294967293"
@@ -519,32 +523,32 @@
 }
 
 
-type rshTest struct {
+type intShiftTest struct {
 	in    string
-	shift int
+	shift uint
 	out   string
 }
 
 
-var rshTests = []rshTest{
-	rshTest{"0", 0, "0"},
-	rshTest{"0", 1, "0"},
-	rshTest{"0", 2, "0"},
-	rshTest{"1", 0, "1"},
-	rshTest{"1", 1, "0"},
-	rshTest{"1", 2, "0"},
-	rshTest{"2", 0, "2"},
-	rshTest{"2", 1, "1"},
-	rshTest{"2", 2, "0"},
-	rshTest{"4294967296", 0, "4294967296"},
-	rshTest{"4294967296", 1, "2147483648"},
-	rshTest{"4294967296", 2, "1073741824"},
-	rshTest{"18446744073709551616", 0, "18446744073709551616"},
-	rshTest{"18446744073709551616", 1, "9223372036854775808"},
-	rshTest{"18446744073709551616", 2, "4611686018427387904"},
-	rshTest{"18446744073709551616", 64, "1"},
-	rshTest{"340282366920938463463374607431768211456", 64, "18446744073709551616"},
-	rshTest{"340282366920938463463374607431768211456", 128, "1"},
+var rshTests = []intShiftTest{
+	intShiftTest{"0", 0, "0"},
+	intShiftTest{"0", 1, "0"},
+	intShiftTest{"0", 2, "0"},
+	intShiftTest{"1", 0, "1"},
+	intShiftTest{"1", 1, "0"},
+	intShiftTest{"1", 2, "0"},
+	intShiftTest{"2", 0, "2"},
+	intShiftTest{"2", 1, "1"},
+	intShiftTest{"2", 2, "0"},
+	intShiftTest{"4294967296", 0, "4294967296"},
+	intShiftTest{"4294967296", 1, "2147483648"},
+	intShiftTest{"4294967296", 2, "1073741824"},
+	intShiftTest{"18446744073709551616", 0, "18446744073709551616"},
+	intShiftTest{"18446744073709551616", 1, "9223372036854775808"},
+	intShiftTest{"18446744073709551616", 2, "4611686018427387904"},
+	intShiftTest{"18446744073709551616", 64, "1"},
+	intShiftTest{"340282366920938463463374607431768211456", 64, "18446744073709551616"},
+	intShiftTest{"340282366920938463463374607431768211456", 128, "1"},
 }
 
 
@@ -559,3 +563,112 @@
 		}
 	}
 }
+
+
+func TestRshSelf(t *testing.T) {
+	for i, test := range rshTests {
+		z, _ := new(Int).SetString(test.in, 10)
+		expected, _ := new(Int).SetString(test.out, 10)
+		z.Rsh(z, test.shift)
+
+		if z.Cmp(expected) != 0 {
+			t.Errorf("#%d got %s want %s", i, z, expected)
+		}
+	}
+}
+
+
+var lshTests = []intShiftTest{
+	intShiftTest{"0", 0, "0"},
+	intShiftTest{"0", 1, "0"},
+	intShiftTest{"0", 2, "0"},
+	intShiftTest{"1", 0, "1"},
+	intShiftTest{"1", 1, "2"},
+	intShiftTest{"1", 2, "4"},
+	intShiftTest{"2", 0, "2"},
+	intShiftTest{"2", 1, "4"},
+	intShiftTest{"2", 2, "8"},
+	intShiftTest{"-87", 1, "-174"},
+	intShiftTest{"4294967296", 0, "4294967296"},
+	intShiftTest{"4294967296", 1, "8589934592"},
+	intShiftTest{"4294967296", 2, "17179869184"},
+	intShiftTest{"18446744073709551616", 0, "18446744073709551616"},
+	intShiftTest{"9223372036854775808", 1, "18446744073709551616"},
+	intShiftTest{"4611686018427387904", 2, "18446744073709551616"},
+	intShiftTest{"1", 64, "18446744073709551616"},
+	intShiftTest{"18446744073709551616", 64, "340282366920938463463374607431768211456"},
+	intShiftTest{"1", 128, "340282366920938463463374607431768211456"},
+}
+
+
+func TestLsh(t *testing.T) {
+	for i, test := range lshTests {
+		in, _ := new(Int).SetString(test.in, 10)
+		expected, _ := new(Int).SetString(test.out, 10)
+		out := new(Int).Lsh(in, test.shift)
+
+		if out.Cmp(expected) != 0 {
+			t.Errorf("#%d got %s want %s", i, out, expected)
+		}
+	}
+}
+
+
+func TestLshSelf(t *testing.T) {
+	for i, test := range lshTests {
+		z, _ := new(Int).SetString(test.in, 10)
+		expected, _ := new(Int).SetString(test.out, 10)
+		z.Lsh(z, test.shift)
+
+		if z.Cmp(expected) != 0 {
+			t.Errorf("#%d got %s want %s", i, z, expected)
+		}
+	}
+}
+
+
+func TestLshRsh(t *testing.T) {
+	for i, test := range rshTests {
+		in, _ := new(Int).SetString(test.in, 10)
+		out := new(Int).Lsh(in, test.shift)
+		out = out.Rsh(out, test.shift)
+
+		if in.Cmp(out) != 0 {
+			t.Errorf("#%d got %s want %s", i, out, in)
+		}
+	}
+	for i, test := range lshTests {
+		in, _ := new(Int).SetString(test.in, 10)
+		out := new(Int).Lsh(in, test.shift)
+		out.Rsh(out, test.shift)
+
+		if in.Cmp(out) != 0 {
+			t.Errorf("#%d got %s want %s", i, out, in)
+		}
+	}
+}
+
+
+var int64Tests = []int64{
+	0,
+	1,
+	-1,
+	4294967295,
+	-4294967295,
+	4294967296,
+	-4294967296,
+	9223372036854775807,
+	-9223372036854775807,
+	-9223372036854775808,
+}
+
+func TestInt64(t *testing.T) {
+	for i, testVal := range int64Tests {
+		in := NewInt(testVal)
+		out := in.Int64()
+
+		if out != testVal {
+			t.Errorf("#%d got %d want %d", i, out, testVal)
+		}
+	}
+}