source: code/trunk/vendor/github.com/remyoudompheng/bigfft/scan.go@ 822

Last change on this file since 822 was 822, checked in by yakumo.izuru, 22 months ago

Prefer immortal.run over runit and rc.d, use vendored modules
for convenience.

Signed-off-by: Izuru Yakumo <yakumo.izuru@…>

File size: 1.6 KB
RevLine 
[822]1package bigfft
2
3import (
4 "math/big"
5)
6
7// FromDecimalString converts the base 10 string
8// representation of a natural (non-negative) number
9// into a *big.Int.
10// Its asymptotic complexity is less than quadratic.
11func FromDecimalString(s string) *big.Int {
12 var sc scanner
13 z := new(big.Int)
14 sc.scan(z, s)
15 return z
16}
17
18type scanner struct {
19 // powers[i] is 10^(2^i * quadraticScanThreshold).
20 powers []*big.Int
21}
22
23func (s *scanner) chunkSize(size int) (int, *big.Int) {
24 if size <= quadraticScanThreshold {
25 panic("size < quadraticScanThreshold")
26 }
27 pow := uint(0)
28 for n := size; n > quadraticScanThreshold; n /= 2 {
29 pow++
30 }
31 // threshold * 2^(pow-1) <= size < threshold * 2^pow
32 return quadraticScanThreshold << (pow - 1), s.power(pow - 1)
33}
34
35func (s *scanner) power(k uint) *big.Int {
36 for i := len(s.powers); i <= int(k); i++ {
37 z := new(big.Int)
38 if i == 0 {
39 if quadraticScanThreshold%14 != 0 {
40 panic("quadraticScanThreshold % 14 != 0")
41 }
42 z.Exp(big.NewInt(1e14), big.NewInt(quadraticScanThreshold/14), nil)
43 } else {
44 z.Mul(s.powers[i-1], s.powers[i-1])
45 }
46 s.powers = append(s.powers, z)
47 }
48 return s.powers[k]
49}
50
51func (s *scanner) scan(z *big.Int, str string) {
52 if len(str) <= quadraticScanThreshold {
53 z.SetString(str, 10)
54 return
55 }
56 sz, pow := s.chunkSize(len(str))
57 // Scan the left half.
58 s.scan(z, str[:len(str)-sz])
59 // FIXME: reuse temporaries.
60 left := Mul(z, pow)
61 // Scan the right half
62 s.scan(z, str[len(str)-sz:])
63 z.Add(z, left)
64}
65
66// quadraticScanThreshold is the number of digits
67// below which big.Int.SetString is more efficient
68// than subquadratic algorithms.
69// 1232 digits fit in 4096 bits.
70const quadraticScanThreshold = 1232
Note: See TracBrowser for help on using the repository browser.