mirror of
https://github.com/golang/go.git
synced 2025-05-30 11:51:34 +00:00
- gcd, exponentiation, population count
- more rational numbers stuff - more tests R=r OCL=18295 CL=18295
This commit is contained in:
parent
16fd356679
commit
db27d309d1
@ -262,6 +262,38 @@ func (x *Natural) Mul(y *Natural) *Natural {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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) {
|
func Shl1(x, c Digit, s uint) (Digit, Digit) {
|
||||||
assert(s <= LogB);
|
assert(s <= LogB);
|
||||||
return x >> (LogB - s), x << s & M | c
|
return x >> (LogB - s), x << s & M | c
|
||||||
@ -490,7 +522,7 @@ func (x *Natural) Cmp(y *Natural) int {
|
|||||||
|
|
||||||
func Log1(x Digit) int {
|
func Log1(x Digit) int {
|
||||||
n := -1;
|
n := -1;
|
||||||
for x != 0 { x >>= 1; n++; }
|
for x != 0 { x = x >> 1; n++; } // BUG >>= broken for uint64
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -624,6 +656,15 @@ export func Fact(n Digit) *Natural {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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 {
|
func HexValue(ch byte) Digit {
|
||||||
d := Digit(1 << LogH);
|
d := Digit(1 << LogH);
|
||||||
switch {
|
switch {
|
||||||
@ -650,6 +691,23 @@ export func NatFromString(s string, base Digit) *Natural {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// 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
|
// Integer numbers
|
||||||
|
|
||||||
@ -717,6 +775,18 @@ func (x *Integer) Mul(y *Integer) *Integer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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 {
|
func (x *Integer) Div(y *Integer) *Integer {
|
||||||
panic("UNIMPLEMENTED");
|
panic("UNIMPLEMENTED");
|
||||||
return nil;
|
return nil;
|
||||||
@ -765,29 +835,36 @@ export type Rational struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func NewRat(a, b *Integer) *Rational {
|
func (x *Rational) Normalize() *Rational {
|
||||||
// TODO normalize the rational
|
f := x.a.mant.Gcd(x.b.mant);
|
||||||
return &Rational{a, b};
|
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 {
|
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 {
|
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 {
|
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 {
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -129,11 +129,47 @@ func TestMod() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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() {
|
func main() {
|
||||||
TestConv();
|
TestConv();
|
||||||
TestShift();
|
TestShift();
|
||||||
TestMul();
|
TestMul();
|
||||||
TestDiv();
|
TestDiv();
|
||||||
TestMod();
|
TestMod();
|
||||||
|
TestGcd();
|
||||||
|
TestPow();
|
||||||
|
TestPop();
|
||||||
print("PASSED\n");
|
print("PASSED\n");
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user