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