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 7package main 8 9import ( 10 big "." 11 "fmt" 12 "runtime" 13) 14 15var ( 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 24func 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 37func 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 45func 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 51func 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} 74