]> Cypherpunks.ru repositories - gostls13.git/blob - misc/cgo/gmp/pi.go
5ea034900a9b172a92fc6b716135f6450c4f5767
[gostls13.git] / misc / cgo / gmp / pi.go
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 //go:build ignore
6 // +build ignore
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 }