Commit 00dc6e96 authored by Robert Griesemer's avatar Robert Griesemer

- fixed another test (arithmetic vs. logic shift bug)

R=r
OCL=18235
CL=18237
parent 15fa1e40
...@@ -99,6 +99,15 @@ export func Dump3(x *[]Digit3) { ...@@ -99,6 +99,15 @@ export func Dump3(x *[]Digit3) {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Natural numbers // 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 type Natural []Digit;
export var NatZero *Natural = new(Natural, 0); export var NatZero *Natural = new(Natural, 0);
...@@ -156,8 +165,8 @@ func (x *Natural) Add(y *Natural) *Natural { ...@@ -156,8 +165,8 @@ func (x *Natural) Add(y *Natural) *Natural {
z := new(Natural, n + 1); z := new(Natural, n + 1);
c := Digit(0); c := Digit(0);
for i := 0; i < m; i++ { c, z[i] = Split(x[i] + y[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(x[i] + c); } for i := m; i < n; i++ { c, z[i] = Split(c + x[i]); }
z[n] = c; z[n] = c;
return Normalize(z); return Normalize(z);
...@@ -171,8 +180,14 @@ func (x *Natural) Sub(y *Natural) *Natural { ...@@ -171,8 +180,14 @@ func (x *Natural) Sub(y *Natural) *Natural {
z := new(Natural, n); z := new(Natural, n);
c := Digit(0); c := Digit(0);
for i := 0; i < m; i++ { c, z[i] = Split(x[i] - y[i] + c); } // TODO verify asr!!! for i := 0; i < m; i++ {
for i := m; i < n; i++ { c, z[i] = Split(x[i] + c); } 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 assert(c == 0); // x.Sub(y) must be called with x >= y
return Normalize(z); return Normalize(z);
...@@ -185,7 +200,7 @@ func (x* Natural) MulAdd1(a, c Digit) *Natural { ...@@ -185,7 +200,7 @@ func (x* Natural) MulAdd1(a, c Digit) *Natural {
n := len(x); n := len(x);
z := new(Natural, n + 1); 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; z[n] = c;
return Normalize(z); return Normalize(z);
...@@ -234,9 +249,9 @@ func (x *Natural) Mul(y *Natural) *Natural { ...@@ -234,9 +249,9 @@ func (x *Natural) Mul(y *Natural) *Natural {
if d != 0 { if d != 0 {
c := Digit(0); c := Digit(0);
for i := 0; i < n; i++ { 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); 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; c += z1;
} }
z[n+j] = c; z[n+j] = c;
...@@ -336,7 +351,7 @@ func Split3(x Digit) (Digit, Digit3) { ...@@ -336,7 +351,7 @@ func Split3(x Digit) (Digit, Digit3) {
func Product(x *[]Digit3, y Digit) { func Product(x *[]Digit3, y Digit) {
n := len(x); n := len(x);
c := Digit(0); 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); assert(c == 0);
} }
...@@ -413,7 +428,8 @@ func DivMod(x, y *[]Digit3) (*[]Digit3, *[]Digit3) { ...@@ -413,7 +428,8 @@ func DivMod(x, y *[]Digit3) (*[]Digit3, *[]Digit3) {
// subtract y*q // subtract y*q
c := Digit(0); c := Digit(0);
for j := 0; j < m; j++ { 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 // correct if trial digit was too large
...@@ -423,6 +439,7 @@ func DivMod(x, y *[]Digit3) (*[]Digit3, *[]Digit3) { ...@@ -423,6 +439,7 @@ func DivMod(x, y *[]Digit3) (*[]Digit3, *[]Digit3) {
for j := 0; j < m; j++ { for j := 0; j < m; j++ {
c, x[i+j] = Split3(c + Digit(x[i+j]) + Digit(y[j])); c, x[i+j] = Split3(c + Digit(x[i+j]) + Digit(y[j]));
} }
assert(c + Digit(x[k]) == 0);
// correct trial digit // correct trial digit
q--; q--;
} }
......
...@@ -30,9 +30,9 @@ func TEST(n uint, b bool) { ...@@ -30,9 +30,9 @@ func TEST(n uint, b bool) {
func TEST_EQ(n uint, x, y *Big.Natural) { func TEST_EQ(n uint, x, y *Big.Natural) {
if x.Cmp(y) != 0 { if x.Cmp(y) != 0 {
println("TEST failed: ", test_msg, "(", n, ")\n"); println("TEST failed:", test_msg, "(", n, ")\n");
println("x = ", x.String(10)); println("x =", x.String(10));
println("y = ", y.String(10)); println("y =", y.String(10));
panic(); panic();
} }
} }
...@@ -122,7 +122,7 @@ func TestMod() { ...@@ -122,7 +122,7 @@ func TestMod() {
TEST_EQ(i, c.Add(d).Mod(c), d); TEST_EQ(i, c.Add(d).Mod(c), d);
} else { } else {
TEST_EQ(i, c.Add(d).Div(c), Big.Nat(2)); 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; break;
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment