mirror of
https://github.com/golang/go
synced 2024-11-25 22:47:57 -07:00
- lowercase non-exported functions in bignum
R=r DELTA=117 (1 added, 0 deleted, 116 changed) OCL=22764 CL=22863
This commit is contained in:
parent
aa1264472e
commit
364a852027
@ -11,7 +11,8 @@ package bignum
|
|||||||
// - Integer signed integer numbers
|
// - Integer signed integer numbers
|
||||||
// - Rational rational numbers
|
// - Rational rational numbers
|
||||||
|
|
||||||
import Fmt "fmt"
|
import "fmt"
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Internal representation
|
// Internal representation
|
||||||
@ -51,27 +52,27 @@ import Fmt "fmt"
|
|||||||
// results are packed again. For faster unpacking/packing, the base size
|
// results are packed again. For faster unpacking/packing, the base size
|
||||||
// in bits must be even.
|
// in bits must be even.
|
||||||
|
|
||||||
type (
|
export type (
|
||||||
Digit uint64;
|
Digit uint64;
|
||||||
Digit2 uint32; // half-digits for division
|
Digit2 uint32; // half-digits for division
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
const LogW = 64;
|
const _LogW = 64;
|
||||||
const LogH = 4; // bits for a hex digit (= "small" number)
|
const _LogH = 4; // bits for a hex digit (= "small" number)
|
||||||
const LogB = LogW - LogH; // largest bit-width available
|
const _LogB = _LogW - _LogH; // largest bit-width available
|
||||||
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// half-digits
|
// half-digits
|
||||||
W2 = LogB / 2; // width
|
_W2 = _LogB / 2; // width
|
||||||
B2 = 1 << W2; // base
|
_B2 = 1 << _W2; // base
|
||||||
M2 = B2 - 1; // mask
|
_M2 = _B2 - 1; // mask
|
||||||
|
|
||||||
// full digits
|
// full digits
|
||||||
W = W2 * 2; // width
|
_W = _W2 * 2; // width
|
||||||
B = 1 << W; // base
|
_B = 1 << _W; // base
|
||||||
M = B - 1; // mask
|
_M = _B - 1; // mask
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -86,7 +87,7 @@ func assert(p bool) {
|
|||||||
|
|
||||||
|
|
||||||
func IsSmall(x Digit) bool {
|
func IsSmall(x Digit) bool {
|
||||||
return x < 1<<LogH;
|
return x < 1<<_LogH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -129,7 +130,7 @@ export func Nat(x uint) Natural {
|
|||||||
case 2: return NatTwo;
|
case 2: return NatTwo;
|
||||||
case 10: return NatTen;
|
case 10: return NatTen;
|
||||||
}
|
}
|
||||||
assert(Digit(x) < B);
|
assert(Digit(x) < _B);
|
||||||
return Natural{Digit(x)};
|
return Natural{Digit(x)};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,7 +149,7 @@ func (x Natural) IsZero() bool {
|
|||||||
|
|
||||||
// Operations
|
// Operations
|
||||||
|
|
||||||
func Normalize(x Natural) Natural {
|
func normalize(x Natural) Natural {
|
||||||
n := len(x);
|
n := len(x);
|
||||||
for n > 0 && x[n - 1] == 0 { n-- }
|
for n > 0 && x[n - 1] == 0 { n-- }
|
||||||
if n < len(x) {
|
if n < len(x) {
|
||||||
@ -170,12 +171,12 @@ func (x Natural) Add(y Natural) Natural {
|
|||||||
i := 0;
|
i := 0;
|
||||||
for i < m {
|
for i < m {
|
||||||
t := c + x[i] + y[i];
|
t := c + x[i] + y[i];
|
||||||
c, z[i] = t>>W, t&M;
|
c, z[i] = t>>_W, t&_M;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
for i < n {
|
for i < n {
|
||||||
t := c + x[i];
|
t := c + x[i];
|
||||||
c, z[i] = t>>W, t&M;
|
c, z[i] = t>>_W, t&_M;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if c != 0 {
|
if c != 0 {
|
||||||
@ -199,12 +200,12 @@ func (x Natural) Sub(y Natural) Natural {
|
|||||||
i := 0;
|
i := 0;
|
||||||
for i < m {
|
for i < m {
|
||||||
t := c + x[i] - y[i];
|
t := c + x[i] - y[i];
|
||||||
c, z[i] = Digit(int64(t)>>W), t&M; // requires arithmetic shift!
|
c, z[i] = Digit(int64(t)>>_W), t&_M; // requires arithmetic shift!
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
for i < n {
|
for i < n {
|
||||||
t := c + x[i];
|
t := c + x[i];
|
||||||
c, z[i] = Digit(int64(t)>>W), t&M; // requires arithmetic shift!
|
c, z[i] = Digit(int64(t)>>_W), t&_M; // requires arithmetic shift!
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
for i > 0 && z[i - 1] == 0 { // normalize
|
for i > 0 && z[i - 1] == 0 { // normalize
|
||||||
@ -216,7 +217,7 @@ func (x Natural) Sub(y Natural) Natural {
|
|||||||
|
|
||||||
|
|
||||||
// Returns c = x*y div B, z = x*y mod B.
|
// Returns c = x*y div B, z = x*y mod B.
|
||||||
func Mul11(x, y Digit) (Digit, Digit) {
|
func mul11(x, y Digit) (Digit, Digit) {
|
||||||
// Split x and y into 2 sub-digits each,
|
// Split x and y into 2 sub-digits each,
|
||||||
// multiply the digits separately while avoiding overflow,
|
// multiply the digits separately while avoiding overflow,
|
||||||
// and return the product as two separate digits.
|
// and return the product as two separate digits.
|
||||||
@ -224,10 +225,10 @@ func Mul11(x, y Digit) (Digit, Digit) {
|
|||||||
// This code also works for non-even bit widths W
|
// This code also works for non-even bit widths W
|
||||||
// which is why there are separate constants below
|
// which is why there are separate constants below
|
||||||
// for half-digits.
|
// for half-digits.
|
||||||
const W2 = (W + 1)/2;
|
const W2 = (_W + 1)/2;
|
||||||
const DW = W2*2 - W; // 0 or 1
|
const DW = W2*2 - _W; // 0 or 1
|
||||||
const B2 = 1<<W2;
|
const B2 = 1<<W2;
|
||||||
const M2 = B2 - 1;
|
const M2 = _B2 - 1;
|
||||||
|
|
||||||
// split x and y into sub-digits
|
// split x and y into sub-digits
|
||||||
// x = (x1*B2 + x0)
|
// x = (x1*B2 + x0)
|
||||||
@ -242,8 +243,8 @@ func Mul11(x, y Digit) (Digit, Digit) {
|
|||||||
|
|
||||||
// compute the result digits but avoid overflow
|
// compute the result digits but avoid overflow
|
||||||
// z = z1*B + z0 = x*y
|
// z = z1*B + z0 = x*y
|
||||||
z0 := (t1<<W2 + t0)&M;
|
z0 := (t1<<W2 + t0)&_M;
|
||||||
z1 := t2<<DW + (t1 + t0>>W2)>>(W-W2);
|
z1 := t2<<DW + (t1 + t0>>W2)>>(_W-W2);
|
||||||
|
|
||||||
return z1, z0;
|
return z1, z0;
|
||||||
}
|
}
|
||||||
@ -260,16 +261,16 @@ func (x Natural) Mul(y Natural) Natural {
|
|||||||
c := Digit(0);
|
c := Digit(0);
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
// z[i+j] += c + x[i]*d;
|
// z[i+j] += c + x[i]*d;
|
||||||
z1, z0 := Mul11(x[i], d);
|
z1, z0 := mul11(x[i], d);
|
||||||
t := c + z[i+j] + z0;
|
t := c + z[i+j] + z0;
|
||||||
c, z[i+j] = t>>W, t&M;
|
c, z[i+j] = t>>_W, t&_M;
|
||||||
c += z1;
|
c += z1;
|
||||||
}
|
}
|
||||||
z[n+j] = c;
|
z[n+j] = c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Normalize(z);
|
return normalize(z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -278,13 +279,13 @@ func (x Natural) Mul(y Natural) Natural {
|
|||||||
// into operands with twice as many digits of half the size (Digit2), do
|
// into operands with twice as many digits of half the size (Digit2), do
|
||||||
// DivMod, and then pack the results again.
|
// DivMod, and then pack the results again.
|
||||||
|
|
||||||
func Unpack(x Natural) []Digit2 {
|
func unpack(x Natural) []Digit2 {
|
||||||
n := len(x);
|
n := len(x);
|
||||||
z := make([]Digit2, n*2 + 1); // add space for extra digit (used by DivMod)
|
z := make([]Digit2, n*2 + 1); // add space for extra digit (used by DivMod)
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
t := x[i];
|
t := x[i];
|
||||||
z[i*2] = Digit2(t & M2);
|
z[i*2] = Digit2(t & _M2);
|
||||||
z[i*2 + 1] = Digit2(t >> W2 & M2);
|
z[i*2 + 1] = Digit2(t >> _W2 & _M2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// normalize result
|
// normalize result
|
||||||
@ -294,7 +295,7 @@ func Unpack(x Natural) []Digit2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func Pack(x []Digit2) Natural {
|
func pack(x []Digit2) Natural {
|
||||||
n := (len(x) + 1) / 2;
|
n := (len(x) + 1) / 2;
|
||||||
z := make(Natural, n);
|
z := make(Natural, n);
|
||||||
if len(x) & 1 == 1 {
|
if len(x) & 1 == 1 {
|
||||||
@ -303,37 +304,37 @@ func Pack(x []Digit2) Natural {
|
|||||||
z[n] = Digit(x[n*2]);
|
z[n] = Digit(x[n*2]);
|
||||||
}
|
}
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
z[i] = Digit(x[i*2 + 1]) << W2 | Digit(x[i*2]);
|
z[i] = Digit(x[i*2 + 1]) << _W2 | Digit(x[i*2]);
|
||||||
}
|
}
|
||||||
return Normalize(z);
|
return normalize(z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func Mul1(z, x []Digit2, y Digit2) Digit2 {
|
func mul1(z, x []Digit2, y Digit2) Digit2 {
|
||||||
n := len(x);
|
n := len(x);
|
||||||
c := Digit(0);
|
c := Digit(0);
|
||||||
f := Digit(y);
|
f := Digit(y);
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
t := c + Digit(x[i])*f;
|
t := c + Digit(x[i])*f;
|
||||||
c, z[i] = t>>W2, Digit2(t&M2);
|
c, z[i] = t>>_W2, Digit2(t&_M2);
|
||||||
}
|
}
|
||||||
return Digit2(c);
|
return Digit2(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func Div1(z, x []Digit2, y Digit2) Digit2 {
|
func div1(z, x []Digit2, y Digit2) Digit2 {
|
||||||
n := len(x);
|
n := len(x);
|
||||||
c := Digit(0);
|
c := Digit(0);
|
||||||
d := Digit(y);
|
d := Digit(y);
|
||||||
for i := n-1; i >= 0; i-- {
|
for i := n-1; i >= 0; i-- {
|
||||||
t := c*B2 + Digit(x[i]);
|
t := c*_B2 + Digit(x[i]);
|
||||||
c, z[i] = t%d, Digit2(t/d);
|
c, z[i] = t%d, Digit2(t/d);
|
||||||
}
|
}
|
||||||
return Digit2(c);
|
return Digit2(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// DivMod returns q and r with x = y*q + r and 0 <= r < y.
|
// divmod returns q and r with x = y*q + r and 0 <= r < y.
|
||||||
// x and y are destroyed in the process.
|
// x and y are destroyed in the process.
|
||||||
//
|
//
|
||||||
// The algorithm used here is based on 1). 2) describes the same algorithm
|
// The algorithm used here is based on 1). 2) describes the same algorithm
|
||||||
@ -353,7 +354,7 @@ func Div1(z, x []Digit2, y Digit2) Digit2 {
|
|||||||
// minefield. "Software - Practice and Experience 24", (June 1994),
|
// minefield. "Software - Practice and Experience 24", (June 1994),
|
||||||
// 579-601. John Wiley & Sons, Ltd.
|
// 579-601. John Wiley & Sons, Ltd.
|
||||||
|
|
||||||
func DivMod(x, y []Digit2) ([]Digit2, []Digit2) {
|
func divmod(x, y []Digit2) ([]Digit2, []Digit2) {
|
||||||
n := len(x);
|
n := len(x);
|
||||||
m := len(y);
|
m := len(y);
|
||||||
if m == 0 {
|
if m == 0 {
|
||||||
@ -366,7 +367,7 @@ func DivMod(x, y []Digit2) ([]Digit2, []Digit2) {
|
|||||||
if m == 1 {
|
if m == 1 {
|
||||||
// division by single digit
|
// division by single digit
|
||||||
// result is shifted left by 1 in place!
|
// result is shifted left by 1 in place!
|
||||||
x[0] = Div1(x[1 : n+1], x[0 : n], y[0]);
|
x[0] = div1(x[1 : n+1], x[0 : n], y[0]);
|
||||||
|
|
||||||
} else if m > n {
|
} else if m > n {
|
||||||
// y > x => quotient = 0, remainder = x
|
// y > x => quotient = 0, remainder = x
|
||||||
@ -381,15 +382,15 @@ func DivMod(x, y []Digit2) ([]Digit2, []Digit2) {
|
|||||||
// TODO Instead of multiplying, it would be sufficient to
|
// TODO Instead of multiplying, it would be sufficient to
|
||||||
// shift y such that the normalization condition is
|
// shift y such that the normalization condition is
|
||||||
// satisfied (as done in "Hacker's Delight").
|
// satisfied (as done in "Hacker's Delight").
|
||||||
f := B2 / (Digit(y[m-1]) + 1);
|
f := _B2 / (Digit(y[m-1]) + 1);
|
||||||
if f != 1 {
|
if f != 1 {
|
||||||
Mul1(x, x, Digit2(f));
|
mul1(x, x, Digit2(f));
|
||||||
Mul1(y, y, Digit2(f));
|
mul1(y, y, Digit2(f));
|
||||||
}
|
}
|
||||||
assert(B2/2 <= y[m-1] && y[m-1] < B2); // incorrect scaling
|
assert(_B2/2 <= y[m-1] && y[m-1] < _B2); // incorrect scaling
|
||||||
|
|
||||||
y1, y2 := Digit(y[m-1]), Digit(y[m-2]);
|
y1, y2 := Digit(y[m-1]), Digit(y[m-2]);
|
||||||
d2 := Digit(y1)<<W2 + Digit(y2);
|
d2 := Digit(y1)<<_W2 + Digit(y2);
|
||||||
for i := n-m; i >= 0; i-- {
|
for i := n-m; i >= 0; i-- {
|
||||||
k := i+m;
|
k := i+m;
|
||||||
|
|
||||||
@ -397,11 +398,11 @@ func DivMod(x, y []Digit2) ([]Digit2, []Digit2) {
|
|||||||
var q Digit;
|
var q Digit;
|
||||||
{ x0, x1, x2 := Digit(x[k]), Digit(x[k-1]), Digit(x[k-2]);
|
{ x0, x1, x2 := Digit(x[k]), Digit(x[k-1]), Digit(x[k-2]);
|
||||||
if x0 != y1 {
|
if x0 != y1 {
|
||||||
q = (x0<<W2 + x1)/y1;
|
q = (x0<<_W2 + x1)/y1;
|
||||||
} else {
|
} else {
|
||||||
q = B2 - 1;
|
q = _B2 - 1;
|
||||||
}
|
}
|
||||||
for y2*q > (x0<<W2 + x1 - y1*q)<<W2 + x2 {
|
for y2*q > (x0<<_W2 + x1 - y1*q)<<_W2 + x2 {
|
||||||
q--
|
q--
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -410,7 +411,7 @@ func DivMod(x, y []Digit2) ([]Digit2, []Digit2) {
|
|||||||
c := Digit(0);
|
c := Digit(0);
|
||||||
for j := 0; j < m; j++ {
|
for j := 0; j < m; j++ {
|
||||||
t := c + Digit(x[i+j]) - Digit(y[j])*q;
|
t := c + Digit(x[i+j]) - Digit(y[j])*q;
|
||||||
c, x[i+j] = Digit(int64(t)>>W2), Digit2(t&M2); // requires arithmetic shift!
|
c, x[i+j] = Digit(int64(t) >> _W2), Digit2(t & _M2); // requires arithmetic shift!
|
||||||
}
|
}
|
||||||
|
|
||||||
// correct if trial digit was too large
|
// correct if trial digit was too large
|
||||||
@ -419,7 +420,7 @@ func DivMod(x, y []Digit2) ([]Digit2, []Digit2) {
|
|||||||
c := Digit(0);
|
c := Digit(0);
|
||||||
for j := 0; j < m; j++ {
|
for j := 0; j < m; j++ {
|
||||||
t := c + Digit(x[i+j]) + Digit(y[j]);
|
t := c + Digit(x[i+j]) + Digit(y[j]);
|
||||||
c, x[i+j] = t >> W2, Digit2(t & M2)
|
c, x[i+j] = t >> _W2, Digit2(t & _M2)
|
||||||
}
|
}
|
||||||
assert(c + Digit(x[k]) == 0);
|
assert(c + Digit(x[k]) == 0);
|
||||||
// correct trial digit
|
// correct trial digit
|
||||||
@ -431,7 +432,7 @@ func DivMod(x, y []Digit2) ([]Digit2, []Digit2) {
|
|||||||
|
|
||||||
// undo normalization for remainder
|
// undo normalization for remainder
|
||||||
if f != 1 {
|
if f != 1 {
|
||||||
c := Div1(x[0 : m], x[0 : m], Digit2(f));
|
c := div1(x[0 : m], x[0 : m], Digit2(f));
|
||||||
assert(c == 0);
|
assert(c == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -441,29 +442,29 @@ func DivMod(x, y []Digit2) ([]Digit2, []Digit2) {
|
|||||||
|
|
||||||
|
|
||||||
func (x Natural) Div(y Natural) Natural {
|
func (x Natural) Div(y Natural) Natural {
|
||||||
q, r := DivMod(Unpack(x), Unpack(y));
|
q, r := divmod(unpack(x), unpack(y));
|
||||||
return Pack(q);
|
return pack(q);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (x Natural) Mod(y Natural) Natural {
|
func (x Natural) Mod(y Natural) Natural {
|
||||||
q, r := DivMod(Unpack(x), Unpack(y));
|
q, r := divmod(unpack(x), unpack(y));
|
||||||
return Pack(r);
|
return pack(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (x Natural) DivMod(y Natural) (Natural, Natural) {
|
func (x Natural) DivMod(y Natural) (Natural, Natural) {
|
||||||
q, r := DivMod(Unpack(x), Unpack(y));
|
q, r := divmod(unpack(x), unpack(y));
|
||||||
return Pack(q), Pack(r);
|
return pack(q), pack(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func Shl(z, x []Digit, s uint) Digit {
|
func shl(z, x []Digit, s uint) Digit {
|
||||||
assert(s <= W);
|
assert(s <= _W);
|
||||||
n := len(x);
|
n := len(x);
|
||||||
c := Digit(0);
|
c := Digit(0);
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
c, z[i] = x[i] >> (W-s), x[i] << s & M | c;
|
c, z[i] = x[i] >> (_W-s), x[i] << s & _M | c;
|
||||||
}
|
}
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@ -471,21 +472,21 @@ func Shl(z, x []Digit, s uint) Digit {
|
|||||||
|
|
||||||
func (x Natural) Shl(s uint) Natural {
|
func (x Natural) Shl(s uint) Natural {
|
||||||
n := uint(len(x));
|
n := uint(len(x));
|
||||||
m := n + s/W;
|
m := n + s/_W;
|
||||||
z := make(Natural, m+1);
|
z := make(Natural, m+1);
|
||||||
|
|
||||||
z[m] = Shl(z[m-n : m], x, s%W);
|
z[m] = shl(z[m-n : m], x, s%_W);
|
||||||
|
|
||||||
return Normalize(z);
|
return normalize(z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func Shr(z, x []Digit, s uint) Digit {
|
func shr(z, x []Digit, s uint) Digit {
|
||||||
assert(s <= W);
|
assert(s <= _W);
|
||||||
n := len(x);
|
n := len(x);
|
||||||
c := Digit(0);
|
c := Digit(0);
|
||||||
for i := n - 1; i >= 0; i-- {
|
for i := n - 1; i >= 0; i-- {
|
||||||
c, z[i] = x[i] << (W-s) & M, x[i] >> s | c;
|
c, z[i] = x[i] << (_W-s) & _M, x[i] >> s | c;
|
||||||
}
|
}
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@ -493,15 +494,15 @@ func Shr(z, x []Digit, s uint) Digit {
|
|||||||
|
|
||||||
func (x Natural) Shr(s uint) Natural {
|
func (x Natural) Shr(s uint) Natural {
|
||||||
n := uint(len(x));
|
n := uint(len(x));
|
||||||
m := n - s/W;
|
m := n - s/_W;
|
||||||
if m > n { // check for underflow
|
if m > n { // check for underflow
|
||||||
m = 0;
|
m = 0;
|
||||||
}
|
}
|
||||||
z := make(Natural, m);
|
z := make(Natural, m);
|
||||||
|
|
||||||
Shr(z, x[n-m : n], s%W);
|
shr(z, x[n-m : n], s%_W);
|
||||||
|
|
||||||
return Normalize(z);
|
return normalize(z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -518,11 +519,11 @@ func (x Natural) And(y Natural) Natural {
|
|||||||
}
|
}
|
||||||
// upper bits are 0
|
// upper bits are 0
|
||||||
|
|
||||||
return Normalize(z);
|
return normalize(z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func Copy(z, x []Digit) {
|
func copy(z, x []Digit) {
|
||||||
for i, e := range x {
|
for i, e := range x {
|
||||||
z[i] = e
|
z[i] = e
|
||||||
}
|
}
|
||||||
@ -540,7 +541,7 @@ func (x Natural) Or(y Natural) Natural {
|
|||||||
for i := 0; i < m; i++ {
|
for i := 0; i < m; i++ {
|
||||||
z[i] = x[i] | y[i];
|
z[i] = x[i] | y[i];
|
||||||
}
|
}
|
||||||
Copy(z[m : n], x[m : n]);
|
copy(z[m : n], x[m : n]);
|
||||||
|
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
@ -557,9 +558,9 @@ func (x Natural) Xor(y Natural) Natural {
|
|||||||
for i := 0; i < m; i++ {
|
for i := 0; i < m; i++ {
|
||||||
z[i] = x[i] ^ y[i];
|
z[i] = x[i] ^ y[i];
|
||||||
}
|
}
|
||||||
Copy(z[m : n], x[m : n]);
|
copy(z[m : n], x[m : n]);
|
||||||
|
|
||||||
return Normalize(z);
|
return normalize(z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -584,7 +585,7 @@ func (x Natural) Cmp(y Natural) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func Log2(x Digit) uint {
|
func log2(x Digit) uint {
|
||||||
assert(x > 0);
|
assert(x > 0);
|
||||||
n := uint(0);
|
n := uint(0);
|
||||||
for x > 0 {
|
for x > 0 {
|
||||||
@ -598,7 +599,7 @@ func Log2(x Digit) uint {
|
|||||||
func (x Natural) Log2() uint {
|
func (x Natural) Log2() uint {
|
||||||
n := len(x);
|
n := len(x);
|
||||||
if n > 0 {
|
if n > 0 {
|
||||||
return (uint(n) - 1)*W + Log2(x[n - 1]);
|
return (uint(n) - 1)*_W + log2(x[n - 1]);
|
||||||
}
|
}
|
||||||
panic("Log2(0)");
|
panic("Log2(0)");
|
||||||
}
|
}
|
||||||
@ -606,16 +607,16 @@ func (x Natural) Log2() uint {
|
|||||||
|
|
||||||
// Computes x = x div d in place (modifies x) for "small" d's.
|
// Computes x = x div d in place (modifies x) for "small" d's.
|
||||||
// Returns updated x and x mod d.
|
// Returns updated x and x mod d.
|
||||||
func DivMod1(x Natural, d Digit) (Natural, Digit) {
|
func divmod1(x Natural, d Digit) (Natural, Digit) {
|
||||||
assert(0 < d && IsSmall(d - 1));
|
assert(0 < d && IsSmall(d - 1));
|
||||||
|
|
||||||
c := Digit(0);
|
c := Digit(0);
|
||||||
for i := len(x) - 1; i >= 0; i-- {
|
for i := len(x) - 1; i >= 0; i-- {
|
||||||
t := c<<W + x[i];
|
t := c<<_W + x[i];
|
||||||
c, x[i] = t%d, t/d;
|
c, x[i] = t%d, t/d;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Normalize(x), c;
|
return normalize(x), c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -626,19 +627,19 @@ func (x Natural) ToString(base uint) string {
|
|||||||
|
|
||||||
// allocate buffer for conversion
|
// allocate buffer for conversion
|
||||||
assert(2 <= base && base <= 16);
|
assert(2 <= base && base <= 16);
|
||||||
n := (x.Log2() + 1) / Log2(Digit(base)) + 1; // +1: round up
|
n := (x.Log2() + 1) / log2(Digit(base)) + 1; // +1: round up
|
||||||
s := make([]byte, n);
|
s := make([]byte, n);
|
||||||
|
|
||||||
// don't destroy x
|
// don't destroy x
|
||||||
t := make(Natural, len(x));
|
t := make(Natural, len(x));
|
||||||
Copy(t, x);
|
copy(t, x);
|
||||||
|
|
||||||
// convert
|
// convert
|
||||||
i := n;
|
i := n;
|
||||||
for !t.IsZero() {
|
for !t.IsZero() {
|
||||||
i--;
|
i--;
|
||||||
var d Digit;
|
var d Digit;
|
||||||
t, d = DivMod1(t, Digit(base));
|
t, d = divmod1(t, Digit(base));
|
||||||
s[i] = "0123456789abcdef"[d];
|
s[i] = "0123456789abcdef"[d];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -651,7 +652,7 @@ func (x Natural) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func FmtBase(c int) uint {
|
func fmtbase(c int) uint {
|
||||||
switch c {
|
switch c {
|
||||||
case 'b': return 2;
|
case 'b': return 2;
|
||||||
case 'o': return 8;
|
case 'o': return 8;
|
||||||
@ -661,13 +662,13 @@ func FmtBase(c int) uint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (x Natural) Format(h Fmt.Formatter, c int) {
|
func (x Natural) Format(h fmt.Formatter, c int) {
|
||||||
Fmt.Fprintf(h, "%s", x.ToString(FmtBase(c)));
|
fmt.Fprintf(h, "%s", x.ToString(fmtbase(c)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func HexValue(ch byte) uint {
|
func hexvalue(ch byte) uint {
|
||||||
d := uint(1 << LogH);
|
d := uint(1 << _LogH);
|
||||||
switch {
|
switch {
|
||||||
case '0' <= ch && ch <= '9': d = uint(ch - '0');
|
case '0' <= ch && ch <= '9': d = uint(ch - '0');
|
||||||
case 'a' <= ch && ch <= 'f': d = uint(ch - 'a') + 10;
|
case 'a' <= ch && ch <= 'f': d = uint(ch - 'a') + 10;
|
||||||
@ -685,11 +686,11 @@ func MulAdd1(x Natural, d, c Digit) Natural {
|
|||||||
|
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
t := c + x[i]*d;
|
t := c + x[i]*d;
|
||||||
c, z[i] = t>>W, t&M;
|
c, z[i] = t>>_W, t&_M;
|
||||||
}
|
}
|
||||||
z[n] = c;
|
z[n] = c;
|
||||||
|
|
||||||
return Normalize(z);
|
return normalize(z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -713,7 +714,7 @@ export func NatFromString(s string, base uint, slen *int) (Natural, uint) {
|
|||||||
assert(2 <= base && base <= 16);
|
assert(2 <= base && base <= 16);
|
||||||
x := Nat(0);
|
x := Nat(0);
|
||||||
for ; i < n; i++ {
|
for ; i < n; i++ {
|
||||||
d := HexValue(s[i]);
|
d := hexvalue(s[i]);
|
||||||
if d < base {
|
if d < base {
|
||||||
x = MulAdd1(x, Digit(base), Digit(d));
|
x = MulAdd1(x, Digit(base), Digit(d));
|
||||||
} else {
|
} else {
|
||||||
@ -732,7 +733,7 @@ export func NatFromString(s string, base uint, slen *int) (Natural, uint) {
|
|||||||
|
|
||||||
// Natural number functions
|
// Natural number functions
|
||||||
|
|
||||||
func Pop1(x Digit) uint {
|
func pop1(x Digit) uint {
|
||||||
n := uint(0);
|
n := uint(0);
|
||||||
for x != 0 {
|
for x != 0 {
|
||||||
x &= x-1;
|
x &= x-1;
|
||||||
@ -745,7 +746,7 @@ func Pop1(x Digit) uint {
|
|||||||
func (x Natural) Pop() uint {
|
func (x Natural) Pop() uint {
|
||||||
n := uint(0);
|
n := uint(0);
|
||||||
for i := len(x) - 1; i >= 0; i-- {
|
for i := len(x) - 1; i >= 0; i-- {
|
||||||
n += Pop1(x[i]);
|
n += pop1(x[i]);
|
||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
@ -1095,8 +1096,8 @@ func (x *Integer) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (x *Integer) Format(h Fmt.Formatter, c int) {
|
func (x *Integer) Format(h fmt.Formatter, c int) {
|
||||||
Fmt.Fprintf(h, "%s", x.ToString(FmtBase(c)));
|
fmt.Fprintf(h, "%s", x.ToString(fmtbase(c)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1225,8 +1226,8 @@ func (x *Rational) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (x *Rational) Format(h Fmt.Formatter, c int) {
|
func (x *Rational) Format(h fmt.Formatter, c int) {
|
||||||
Fmt.Fprintf(h, "%s", x.ToString(FmtBase(c)));
|
fmt.Fprintf(h, "%s", x.ToString(fmtbase(c)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user