assert(n >= m);
z := new(Natural, n + 1);
- i := 0;
c := Word(0);
- for ; i < m; i++ { c, z[i] = Split(x[i] + y[i] + c); }
- for ; i < n; i++ { c, z[i] = Split(x[i] + c); }
- z[i] = c;
+ 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); }
+ z[n] = c;
return Normalize(z);
}
assert(n >= m);
z := new(Natural, n);
- i := 0;
c := Word(0);
- for ; i < m; i++ { c, z[i] = Split(x[i] - y[i] + c); }
- for ; i < n; i++ { c, z[i] = Split(x[i] + c); }
+ 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); }
assert(c == 0); // x.Sub(y) must be called with x >= y
return Normalize(z);
// Computes x = x*a + c (in place) for "small" a's.
func (x* Natural) MulAdd1(a, c Word) *Natural {
assert(IsSmall(a-1) && IsSmall(c));
- if x.IsZero() || a == 0 {
- return NewNat(c);
- }
n := len(x);
-
z := new(Natural, n + 1);
+
for i := 0; i < n; i++ { c, z[i] = Split(x[i]*a + c); }
z[n] = c;
}
-// BUG use these until 6g shifts are working properly
-func shl(x Word, s uint) Word {
- return x << s;
-}
-
-
-func shr(x Word, s uint) Word {
- return x >> s;
+func Shl1(x, c Word, s uint) (Word, Word) {
+ assert(s <= LogB);
+ return x >> (LogB - s), x << s & M | c
}
-func Shl1(x, c Word, s uint) (Word, Word) {
+func Shr1(x, c Word, s uint) (Word, Word) {
assert(s <= LogB);
- return shr(x, (LogB - s)), shl(x, s)&M | c
+ return x << (LogB - s) & M, x >> s | c
}
func (x *Natural) Shl(s uint) *Natural {
n := len(x);
- si := int(s/LogB);
- s = s%LogB;
+ si := int(s / LogB);
+ s = s % LogB;
z := new(Natural, n + si + 1);
- i := 0;
c := Word(0);
- for ; i < n; i++ { c, z[i+si] = Shl1(x[i], c, s); }
- z[i+si] = c;
+ for i := 0; i < n; i++ { c, z[i+si] = Shl1(x[i], c, s); }
+ z[n+si] = c;
return Normalize(z);
}
func (x *Natural) Shr(s uint) *Natural {
- panic("incomplete");
- return nil
+ n := len(x);
+ si := int(s / LogB);
+ if si >= n { si = n; }
+ s = s % LogB;
+ assert(si <= n);
+ z := new(Natural, n - si);
+
+ c := Word(0);
+ for i := n - 1; i >= si; i-- { c, z[i-si] = Shr1(x[i], c, s); }
+
+ return Normalize(z);
}
assert(n >= m);
z := new(Natural, n);
- i := 0;
- for ; i < m; i++ { z[i] = x[i] & y[i]; }
- for ; i < n; i++ { z[i] = x[i]; }
+ for i := 0; i < m; i++ { z[i] = x[i] & y[i]; }
+ for i := m; i < n; i++ { z[i] = x[i]; }
return Normalize(z);
}
assert(n >= m);
z := new(Natural, n);
- i := 0;
- for ; i < m; i++ { z[i] = x[i] | y[i]; }
- for ; i < n; i++ { z[i] = x[i]; }
+ for i := 0; i < m; i++ { z[i] = x[i] | y[i]; }
+ for i := m; i < n; i++ { z[i] = x[i]; }
return Normalize(z);
}
assert(n >= m);
z := new(Natural, n);
- i := 0;
- for ; i < m; i++ { z[i] = x[i] ^ y[i]; }
- for ; i < n; i++ { z[i] = x[i]; }
+ for i := 0; i < m; i++ { z[i] = x[i] ^ y[i]; }
+ for i := m; i < n; i++ { z[i] = x[i]; }
return Normalize(z);
}
func TestShift() {
- test_msg = "TestShiftA";
+ test_msg = "TestShift1L";
TEST(0, b.Shl(0).Cmp(b) == 0);
TEST(1, c.Shl(1).Cmp(c) > 0);
- test_msg = "TestShiftB";
+ test_msg = "TestShift1R";
+ TEST(0, b.Shr(0).Cmp(b) == 0);
+ TEST(1, c.Shr(1).Cmp(c) < 0);
+
+ test_msg = "TestShift2";
+ for i := 0; i < 100; i++ {
+ TEST(i, c.Shl(uint(i)).Shr(uint(i)).Cmp(c) == 0);
+ }
+
+ test_msg = "TestShift3L";
{ const m = 3;
p := b;
f := Bignum.NewNat(1<<m);
p = p.Mul(f);
}
}
+
+ test_msg = "TestShift3R";
+ { p := c;
+ for i := 0; c.Cmp(Bignum.NatZero) == 0; i++ {
+ TEST(i, c.Shr(uint(i)).Cmp(p) == 0);
+ p = p.Shr(1);
+ }
+ }
}