}
+func Pop1(x Digit) uint {
+ n := uint(0);
+ for x != 0 {
+ x &= x-1;
+ n++;
+ }
+ return n;
+}
+
+
+func (x *Natural) Pop() uint {
+ n := uint(0);
+ for i := len(x) - 1; i >= 0; i-- {
+ n += Pop1(x[i]);
+ }
+ return n;
+}
+
+
+func (x *Natural) Pow(n uint) *Natural {
+ z := Nat(1);
+ for n > 0 {
+ // z * x^n == x^n0
+ if n&1 == 1 {
+ z = z.Mul(x);
+ }
+ x, n = x.Mul(x), n/2;
+ }
+ return z;
+}
+
+
func Shl1(x, c Digit, s uint) (Digit, Digit) {
assert(s <= LogB);
return x >> (LogB - s), x << s & M | c
func Log1(x Digit) int {
n := -1;
- for x != 0 { x >>= 1; n++; }
+ for x != 0 { x = x >> 1; n++; } // BUG >>= broken for uint64
return n;
}
}
+func (x *Natural) Gcd(y *Natural) *Natural {
+ // Euclidean algorithm.
+ for !y.IsZero() {
+ x, y = y, x.Mod(y);
+ }
+ return x;
+}
+
+
func HexValue(ch byte) Digit {
d := Digit(1 << LogH);
switch {
}
+// ----------------------------------------------------------------------------
+// Algorithms
+
+export type T interface {
+ IsZero() bool;
+ Mod(y T) bool;
+}
+
+export func Gcd(x, y T) T {
+ // Euclidean algorithm.
+ for !y.IsZero() {
+ x, y = y, x.Mod(y);
+ }
+ return x;
+}
+
+
// ----------------------------------------------------------------------------
// Integer numbers
}
+func (x *Integer) Quo(y *Integer) *Integer {
+ panic("UNIMPLEMENTED");
+ return nil;
+}
+
+
+func (x *Integer) Rem(y *Integer) *Integer {
+ panic("UNIMPLEMENTED");
+ return nil;
+}
+
+
func (x *Integer) Div(y *Integer) *Integer {
panic("UNIMPLEMENTED");
return nil;
}
-func NewRat(a, b *Integer) *Rational {
- // TODO normalize the rational
- return &Rational{a, b};
+func (x *Rational) Normalize() *Rational {
+ f := x.a.mant.Gcd(x.b.mant);
+ x.a.mant = x.a.mant.Div(f);
+ x.b.mant = x.b.mant.Div(f);
+ return x;
+}
+
+
+func Rat(a, b *Integer) *Rational {
+ return (&Rational{a, b}).Normalize();
}
func (x *Rational) Add(y *Rational) *Rational {
- return NewRat((x.a.Mul(y.b)).Add(x.b.Mul(y.a)), x.b.Mul(y.b));
+ return Rat((x.a.Mul(y.b)).Add(x.b.Mul(y.a)), x.b.Mul(y.b));
}
func (x *Rational) Sub(y *Rational) *Rational {
- return NewRat((x.a.Mul(y.b)).Sub(x.b.Mul(y.a)), x.b.Mul(y.b));
+ return Rat((x.a.Mul(y.b)).Sub(x.b.Mul(y.a)), x.b.Mul(y.b));
}
func (x *Rational) Mul(y *Rational) *Rational {
- return NewRat(x.a.Mul(y.a), x.b.Mul(y.b));
+ return Rat(x.a.Mul(y.a), x.b.Mul(y.b));
}
func (x *Rational) Div(y *Rational) *Rational {
- return NewRat(x.a.Mul(y.b), x.b.Mul(y.a));
+ return Rat(x.a.Mul(y.b), x.b.Mul(y.a));
}
}
+func TestGcd() {
+ test_msg = "TestGcdA";
+ f := Big.Nat(99991);
+ TEST_EQ(0, b.Mul(f).Gcd(c.Mul(f)), Big.MulRange(1, 20).Mul(f));
+}
+
+
+func TestPow() {
+ test_msg = "TestPowA";
+ TEST_EQ(0, Big.Nat(2).Pow(0), Big.Nat(1));
+
+ test_msg = "TestPowB";
+ for i := uint(0); i < 100; i++ {
+ TEST_EQ(i, Big.Nat(2).Pow(i), Big.Nat(1).Shl(i));
+ }
+}
+
+
+func TestPop() {
+ test_msg = "TestPopA";
+ TEST(0, Big.Nat(0).Pop() == 0);
+ TEST(1, Big.Nat(1).Pop() == 1);
+ TEST(2, Big.Nat(10).Pop() == 2);
+ TEST(3, Big.Nat(30).Pop() == 4);
+ TEST(4, Big.Nat(0x1248f).Shl(33).Pop() == 8);
+
+ test_msg = "TestPopB";
+ for i := uint(0); i < 100; i++ {
+ TEST(i, Big.Nat(1).Shl(i).Sub(Big.Nat(1)).Pop() == i);
+ }
+}
+
+
func main() {
TestConv();
TestShift();
TestMul();
TestDiv();
TestMod();
+ TestGcd();
+ TestPow();
+ TestPop();
print("PASSED\n");
}