github.com/kidsbmilk/gofronted_all@v0.0.0-20220701224323-6479d5976c5d/libgo/misc/cgo/gmp/pi.go (about) 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 }