]> Cypherpunks repositories - gostls13.git/commitdiff
- fixed another test (arithmetic vs. logic shift bug)
authorRobert Griesemer <gri@golang.org>
Fri, 31 Oct 2008 17:52:59 +0000 (10:52 -0700)
committerRobert Griesemer <gri@golang.org>
Fri, 31 Oct 2008 17:52:59 +0000 (10:52 -0700)
R=r
OCL=18235
CL=18237

usr/gri/bignum/bignum.go
usr/gri/bignum/bignum_test.go

index 7b15bf47636cbf887d128eeccdd0673aba7a7657..95be5787942b4969f42e2c2e82610cc11ff8f5a8 100755 (executable)
@@ -99,6 +99,15 @@ export func Dump3(x *[]Digit3) {
 
 // ----------------------------------------------------------------------------
 // Natural numbers
+//
+// Naming conventions
+//
+// B, b   bases
+// c      carry
+// x, y   operands
+// z      result
+// n, m   n = len(x), m = len(y)
+
 
 export type Natural []Digit;
 export var NatZero *Natural = new(Natural, 0);
@@ -156,8 +165,8 @@ func (x *Natural) Add(y *Natural) *Natural {
        z := new(Natural, n + 1);
 
        c := Digit(0);
-       for i := 0; i < m; i++ { c, z[i] = Split(x[i] + y[i] + c); }
-       for i := m; i < n; i++ { c, z[i] = Split(x[i] + c); }
+       for i := 0; i < m; i++ { c, z[i] = Split(c + x[i] + y[i]); }
+       for i := m; i < n; i++ { c, z[i] = Split(c + x[i]); }
        z[n] = c;
 
        return Normalize(z);
@@ -171,8 +180,14 @@ func (x *Natural) Sub(y *Natural) *Natural {
        z := new(Natural, n);
 
        c := Digit(0);
-       for i := 0; i < m; i++ { c, z[i] = Split(x[i] - y[i] + c); }  // TODO verify asr!!!
-       for i := m; i < n; i++ { c, z[i] = Split(x[i] + c); }
+       for i := 0; i < m; i++ {
+               t := c + x[i] - y[i];
+               c, z[i] = Digit(int64(t)>>L), t&M;  // arithmetic shift!
+       }
+       for i := m; i < n; i++ {
+               t := c + x[i];
+               c, z[i] = Digit(int64(t)>>L), t&M;  // arithmetic shift!
+       }
        assert(c == 0);  // x.Sub(y) must be called with x >= y
 
        return Normalize(z);
@@ -185,7 +200,7 @@ func (x* Natural) MulAdd1(a, c Digit) *Natural {
        n := len(x);
        z := new(Natural, n + 1);
 
-       for i := 0; i < n; i++ { c, z[i] = Split(x[i]*a + c); }
+       for i := 0; i < n; i++ { c, z[i] = Split(c + x[i]*a); }
        z[n] = c;
 
        return Normalize(z);
@@ -234,9 +249,9 @@ func (x *Natural) Mul(y *Natural) *Natural {
                if d != 0 {
                        c := Digit(0);
                        for i := 0; i < n; i++ {
-                               // z[i+j] += x[i]*d + c;
+                               // z[i+j] += c + x[i]*d;
                                z1, z0 := Mul1(x[i], d);
-                               c, z[i+j] = Split(z[i+j] + z0 + c);
+                               c, z[i+j] = Split(c + z[i+j] + z0);
                                c += z1;
                        }
                        z[n+j] = c;
@@ -336,7 +351,7 @@ func Split3(x Digit) (Digit, Digit3) {
 func Product(x *[]Digit3, y Digit) {
        n := len(x);
        c := Digit(0);
-       for i := 0; i < n; i++ { c, x[i] = Split3(Digit(x[i])*y + c) }
+       for i := 0; i < n; i++ { c, x[i] = Split3(c + Digit(x[i])*y) }
        assert(c == 0);
 }
 
@@ -413,7 +428,8 @@ func DivMod(x, y *[]Digit3) (*[]Digit3, *[]Digit3) {
                        // subtract y*q
                        c := Digit(0);
                        for j := 0; j < m; j++ {
-                               c, x[i+j] = Split3(c + Digit(x[i+j]) - Digit(y[j])*q);
+                               t := c + Digit(x[i+j]) - Digit(y[j])*q;  // arithmetic shift!
+                               c, x[i+j] = Digit(int64(t)>>L3), Digit3(t&M3);
                        }
                        
                        // correct if trial digit was too large
@@ -423,6 +439,7 @@ func DivMod(x, y *[]Digit3) (*[]Digit3, *[]Digit3) {
                                for j := 0; j < m; j++ {
                                        c, x[i+j] = Split3(c + Digit(x[i+j]) + Digit(y[j]));
                                }
+                               assert(c + Digit(x[k]) == 0);
                                // correct trial digit
                                q--;
                        }
index 338c70bc85a83f6bc8c7d22cd06928d28758150c..783273b3475609c3c1896aa4bbf65ac706f445e7 100644 (file)
@@ -30,9 +30,9 @@ func TEST(n uint, b bool) {
 
 func TEST_EQ(n uint, x, y *Big.Natural) {
        if x.Cmp(y) != 0 {
-               println("TEST failed: ", test_msg, "(", n, ")\n");
-               println("x = ", x.String(10));
-               println("y = ", y.String(10));
+               println("TEST failed:", test_msg, "(", n, ")\n");
+               println("x =", x.String(10));
+               println("y =", y.String(10));
                panic();
        }
 }
@@ -122,7 +122,7 @@ func TestMod() {
                        TEST_EQ(i, c.Add(d).Mod(c), d);
                } else {
                        TEST_EQ(i, c.Add(d).Div(c), Big.Nat(2));
-                       //TEST_EQ(i, c.Add(d).Mod(c), d.Sub(c));
+                       TEST_EQ(i, c.Add(d).Mod(c), d.Sub(c));
                        break;
                }
        }