mirror of
https://github.com/golang/go
synced 2024-11-12 07:10:22 -07:00
mat/big: add raw access to Int bits
This is a minimal API extension, it makes it possible to implement missing Int functionality externally w/o compromising efficiency. It is the hope that this will reduce the number of feature requests going directly into the big package. Also: Fixed some naming inconsistencies: The receiver is only called z when it is also the result. R=golang-dev, agl CC=golang-dev https://golang.org/cl/5607055
This commit is contained in:
parent
9fb24b9448
commit
71c19b610f
@ -65,6 +65,26 @@ func (z *Int) Set(x *Int) *Int {
|
||||
return z
|
||||
}
|
||||
|
||||
// Bits provides raw (unchecked but fast) access to x by returning its
|
||||
// absolute value as a little-endian Word slice. The result and x share
|
||||
// the same underlying array.
|
||||
// Bits is intended to support implementation of missing low-level Int
|
||||
// functionality outside this package; it should be avoided otherwise.
|
||||
func (x *Int) Bits() []Word {
|
||||
return x.abs
|
||||
}
|
||||
|
||||
// SetBits provides raw (unchecked but fast) access to z by setting its
|
||||
// value to abs, interpreted as a little-endian Word slice, and returning
|
||||
// z. The result and abs share the same underlying array.
|
||||
// SetBits is intended to support implementation of missing low-level Int
|
||||
// functionality outside this package; it should be avoided otherwise.
|
||||
func (z *Int) SetBits(abs []Word) *Int {
|
||||
z.abs = nat(abs).norm()
|
||||
z.neg = false
|
||||
return z
|
||||
}
|
||||
|
||||
// Abs sets z to |x| (the absolute value of x) and returns z.
|
||||
func (z *Int) Abs(x *Int) *Int {
|
||||
z.Set(x)
|
||||
@ -528,18 +548,18 @@ func (z *Int) SetBytes(buf []byte) *Int {
|
||||
}
|
||||
|
||||
// Bytes returns the absolute value of z as a big-endian byte slice.
|
||||
func (z *Int) Bytes() []byte {
|
||||
buf := make([]byte, len(z.abs)*_S)
|
||||
return buf[z.abs.bytes(buf):]
|
||||
func (x *Int) Bytes() []byte {
|
||||
buf := make([]byte, len(x.abs)*_S)
|
||||
return buf[x.abs.bytes(buf):]
|
||||
}
|
||||
|
||||
// BitLen returns the length of the absolute value of z in bits.
|
||||
// The bit length of 0 is 0.
|
||||
func (z *Int) BitLen() int {
|
||||
return z.abs.bitLen()
|
||||
func (x *Int) BitLen() int {
|
||||
return x.abs.bitLen()
|
||||
}
|
||||
|
||||
// Exp sets z = x**y mod m. If m is nil, z = x**y.
|
||||
// Exp sets z = x**y mod m and returns z. If m is nil, z = x**y.
|
||||
// See Knuth, volume 2, section 4.6.3.
|
||||
func (z *Int) Exp(x, y, m *Int) *Int {
|
||||
if y.neg || len(y.abs) == 0 {
|
||||
@ -617,11 +637,11 @@ func GcdInt(d, x, y, a, b *Int) {
|
||||
*d = *A
|
||||
}
|
||||
|
||||
// ProbablyPrime performs n Miller-Rabin tests to check whether z is prime.
|
||||
// If it returns true, z is prime with probability 1 - 1/4^n.
|
||||
// If it returns false, z is not prime.
|
||||
func ProbablyPrime(z *Int, n int) bool {
|
||||
return !z.neg && z.abs.probablyPrime(n)
|
||||
// ProbablyPrime performs n Miller-Rabin tests to check whether x is prime.
|
||||
// If it returns true, x is prime with probability 1 - 1/4^n.
|
||||
// If it returns false, x is not prime.
|
||||
func ProbablyPrime(x *Int, n int) bool {
|
||||
return !x.neg && x.abs.probablyPrime(n)
|
||||
}
|
||||
|
||||
// Rand sets z to a pseudo-random number in [0, n) and returns z.
|
||||
@ -671,18 +691,18 @@ func (z *Int) Rsh(x *Int, n uint) *Int {
|
||||
return z
|
||||
}
|
||||
|
||||
// Bit returns the value of the i'th bit of z. That is, it
|
||||
// returns (z>>i)&1. The bit index i must be >= 0.
|
||||
func (z *Int) Bit(i int) uint {
|
||||
// Bit returns the value of the i'th bit of x. That is, it
|
||||
// returns (x>>i)&1. The bit index i must be >= 0.
|
||||
func (x *Int) Bit(i int) uint {
|
||||
if i < 0 {
|
||||
panic("negative bit index")
|
||||
}
|
||||
if z.neg {
|
||||
t := nat(nil).sub(z.abs, natOne)
|
||||
if x.neg {
|
||||
t := nat(nil).sub(x.abs, natOne)
|
||||
return t.bit(uint(i)) ^ 1
|
||||
}
|
||||
|
||||
return z.abs.bit(uint(i))
|
||||
return x.abs.bit(uint(i))
|
||||
}
|
||||
|
||||
// SetBit sets z to x, with x's i'th bit set to b (0 or 1).
|
||||
@ -847,11 +867,11 @@ func (z *Int) Not(x *Int) *Int {
|
||||
const intGobVersion byte = 1
|
||||
|
||||
// GobEncode implements the gob.GobEncoder interface.
|
||||
func (z *Int) GobEncode() ([]byte, error) {
|
||||
buf := make([]byte, 1+len(z.abs)*_S) // extra byte for version and sign bit
|
||||
i := z.abs.bytes(buf) - 1 // i >= 0
|
||||
func (x *Int) GobEncode() ([]byte, error) {
|
||||
buf := make([]byte, 1+len(x.abs)*_S) // extra byte for version and sign bit
|
||||
i := x.abs.bytes(buf) - 1 // i >= 0
|
||||
b := intGobVersion << 1 // make space for sign bit
|
||||
if z.neg {
|
||||
if x.neg {
|
||||
b |= 1
|
||||
}
|
||||
buf[i] = b
|
||||
|
Loading…
Reference in New Issue
Block a user