1
2
3
4
5
6
7
8 package main
9
10 import (
11 big "."
12 "fmt"
13 "runtime"
14 )
15
16 var (
17 tmp1 = big.NewInt(0)
18 tmp2 = big.NewInt(0)
19 numer = big.NewInt(1)
20 accum = big.NewInt(0)
21 denom = big.NewInt(1)
22 ten = big.NewInt(10)
23 )
24
25 func extractDigit() int64 {
26 if big.CmpInt(numer, accum) > 0 {
27 return -1
28 }
29 tmp1.Lsh(numer, 1).Add(tmp1, numer).Add(tmp1, accum)
30 big.DivModInt(tmp1, tmp2, tmp1, denom)
31 tmp2.Add(tmp2, numer)
32 if big.CmpInt(tmp2, denom) >= 0 {
33 return -1
34 }
35 return tmp1.Int64()
36 }
37
38 func nextTerm(k int64) {
39 y2 := k*2 + 1
40 accum.Add(accum, tmp1.Lsh(numer, 1))
41 accum.Mul(accum, tmp1.SetInt64(y2))
42 numer.Mul(numer, tmp1.SetInt64(k))
43 denom.Mul(denom, tmp1.SetInt64(y2))
44 }
45
46 func eliminateDigit(d int64) {
47 accum.Sub(accum, tmp1.Mul(denom, tmp1.SetInt64(d)))
48 accum.Mul(accum, ten)
49 numer.Mul(numer, ten)
50 }
51
52 func main() {
53 i := 0
54 k := int64(0)
55 for {
56 d := int64(-1)
57 for d < 0 {
58 k++
59 nextTerm(k)
60 d = extractDigit()
61 }
62 eliminateDigit(d)
63 fmt.Printf("%c", d+'0')
64
65 if i++; i%50 == 0 {
66 fmt.Printf("\n")
67 if i >= 1000 {
68 break
69 }
70 }
71 }
72
73 fmt.Printf("\n%d calls; bit sizes: %d %d %d\n", runtime.NumCgoCall(), numer.Len(), accum.Len(), denom.Len())
74 }
75
View as plain text