aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/math/big/nat.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/math/big/nat.go')
-rw-r--r--libgo/go/math/big/nat.go63
1 files changed, 8 insertions, 55 deletions
diff --git a/libgo/go/math/big/nat.go b/libgo/go/math/big/nat.go
index 9b1a626c4cf..889eacb90f0 100644
--- a/libgo/go/math/big/nat.go
+++ b/libgo/go/math/big/nat.go
@@ -9,6 +9,7 @@
package big
import (
+ "math/bits"
"math/rand"
"sync"
)
@@ -67,24 +68,14 @@ func (z nat) setWord(x Word) nat {
}
func (z nat) setUint64(x uint64) nat {
- // single-digit values
+ // single-word value
if w := Word(x); uint64(w) == x {
return z.setWord(w)
}
-
- // compute number of words n required to represent x
- n := 0
- for t := x; t > 0; t >>= _W {
- n++
- }
-
- // split x into n words
- z = z.make(n)
- for i := range z {
- z[i] = Word(x & _M)
- x >>= _W
- }
-
+ // 2-word value
+ z = z.make(2)
+ z[1] = Word(x >> 32)
+ z[0] = Word(x)
return z
}
@@ -653,49 +644,11 @@ func (z nat) divLarge(u, uIn, v nat) (q, r nat) {
// Length of x in bits. x must be normalized.
func (x nat) bitLen() int {
if i := len(x) - 1; i >= 0 {
- return i*_W + bitLen(x[i])
+ return i*_W + bits.Len(uint(x[i]))
}
return 0
}
-const deBruijn32 = 0x077CB531
-
-var deBruijn32Lookup = [...]byte{
- 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
- 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9,
-}
-
-const deBruijn64 = 0x03f79d71b4ca8b09
-
-var deBruijn64Lookup = [...]byte{
- 0, 1, 56, 2, 57, 49, 28, 3, 61, 58, 42, 50, 38, 29, 17, 4,
- 62, 47, 59, 36, 45, 43, 51, 22, 53, 39, 33, 30, 24, 18, 12, 5,
- 63, 55, 48, 27, 60, 41, 37, 16, 46, 35, 44, 21, 52, 32, 23, 11,
- 54, 26, 40, 15, 34, 20, 31, 10, 25, 14, 19, 9, 13, 8, 7, 6,
-}
-
-// trailingZeroBits returns the number of consecutive least significant zero
-// bits of x.
-func trailingZeroBits(x Word) uint {
- // x & -x leaves only the right-most bit set in the word. Let k be the
- // index of that bit. Since only a single bit is set, the value is two
- // to the power of k. Multiplying by a power of two is equivalent to
- // left shifting, in this case by k bits. The de Bruijn constant is
- // such that all six bit, consecutive substrings are distinct.
- // Therefore, if we have a left shifted version of this constant we can
- // find by how many bits it was shifted by looking at which six bit
- // substring ended up at the top of the word.
- // (Knuth, volume 4, section 7.3.1)
- switch _W {
- case 32:
- return uint(deBruijn32Lookup[((x&-x)*deBruijn32)>>27])
- case 64:
- return uint(deBruijn64Lookup[((x&-x)*(deBruijn64&_M))>>58])
- default:
- panic("unknown word size")
- }
-}
-
// trailingZeroBits returns the number of consecutive least significant zero
// bits of x.
func (x nat) trailingZeroBits() uint {
@@ -707,7 +660,7 @@ func (x nat) trailingZeroBits() uint {
i++
}
// x[i] != 0
- return i*_W + trailingZeroBits(x[i])
+ return i*_W + uint(bits.TrailingZeros(uint(x[i])))
}
// z = x << s