mirror of
https://github.com/golang/go
synced 2024-11-26 08:27:56 -07:00
- fixed another test (arithmetic vs. logic shift bug)
R=r OCL=18235 CL=18237
This commit is contained in:
parent
15fa1e4033
commit
00dc6e9678
@ -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 {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
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) {
|
|||||||
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) {
|
|||||||
// 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) {
|
|||||||
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) {
|
|||||||
|
|
||||||
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() {
|
|||||||
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user