# hantmac/Mastering_Go_ZH_CN

Fetching contributors…
Cannot retrieve contributors at this time
141 lines (120 sloc) 5.83 KB

# 计算Pi的精确值

`calculatePi.go`使用Bellard规则计算Pi值，代码将分4部分展示。

```package main

import (
"fmt"
"math"
"math/big"
"os"
"strconv"
)

var precision uint = 0```

`precision`变量代表你想得到的Pi值精度，其声明为全局变量保证在整个程序中都可以被访问到。

```func Pi(accuracy uint) *big.Float {
k := 0
pi := new(big.Float).SetPrec(precision).SetFloat64(0)
k1k2k3 := new(big.Float).SetPrec(precision).SetFloat64(0)
k4k5k6 := new(big.Float).SetPrec(precision).SetFloat64(0)
temp := new(big.Float).SetPrec(precision).SetFloat64(0)
minusOne := new(big.Float).SetPrec(precision).SetFloat64(-1)
total := new(big.Float).SetPrec(precision).SetFloat64(0)

two2Six := math.Pow(2, 6)
two2SixBig := new(big.Float).SetPrec(precision).SetFloat64(two2Six)```

`new(big.Float)`创建一个`big.Float`类型的变量，并调用`SetPrec()`函数将精度设置为参数`precision`

```for {
if k > int(accuracy) {
break
}
t1 := float64(float64(1) / float64(10*k+9))
k1 := new(big.Float).SetPrec(precision).SetFloat64(t1)
t2 := float64(float64(64) / float64(10*k+3))
k2 := new(big.Float).SetPrec(precision).SetFloat64(t2)
t3 := float64(float64(32) / float64(4*k+1))
k3 := new(big.Float).SetPrec(precision).SetFloat64(t3)
k1k2k3.Sub(k1, k2)
k1k2k3.Sub(k1k2k3, k3)

t4 := float64(float64(4) / float64(10*k+5))
k4 := new(big.Float).SetPrec(precision).SetFloat64(t4)
t5 := float64(float64(4) / float64(10*k+7))
k5 := new(big.Float).SetPrec(precision).SetFloat64(t5)
t6 := float64(float64(1) / float64(4*k+3))
k6 := new(big.Float).SetPrec(precision).SetFloat64(t6)
k4k5k6 = k4k5k6.Mul(k4k5k6, minusOne)

k7temp := new(big.Int).Exp(big.NewInt(-1), big.NewInt(int64(k)), nil)
k8temp := new(big.Int).Exp(big.NewInt(1024), big.NewInt(int64(k)), nil)

k7 := new(big.Float).SetPrec(precision).SetFloat64(0)
k7.SetInt(k7temp)
k8 := new(big.Float).SetPrec(precision).SetFloat64(0)
k8.SetInt(k8temp)

t9 := float64(256) / float64(10*k+1)
k9 := new(big.Float).SetPrec(precision).SetFloat64(t9)
total.Mul(k9, k7)
total.Quo(total, k8)

k = k + 1
}
pi.Quo(pi, two2SixBig)
return pi
}```

```func main() {
arguments := os.Args
if len(arguments) == 1 {
os.Exit(1)
}

temp, _ := strconv.ParseUint(arguments[1], 10, 32)
precision = uint(temp) * 3

PI := Pi(precision)
fmt.Println(PI)
}```

\$ go run calculatePi.go

exit status 1

\$ go run calculatePi.go 20

3.141592653589793258

\$ go run calculatePi.go 200

3.141592653589793256960399361738762404019183156248573243493179283571046450248913467118511784317615354282017929416292809050813937875283435610586313363548602436768047706489838924381929

Fabrice Bellard在圆周率算法方面也有着惊人的成就，1997年FabriceBellard提出最快圆周率算法公式。在计算圆周率的过程中，Fabrice Bellard使用改良后的查德诺夫斯基方程算法来进行圆周率的计算，并使用贝利-波温-劳夫算法来验证计算的结果。为了纪念他对圆周率算法所作出的杰出贡献，Fabrice Bellard所使用的改良型算法被命名为Fabrice Bellard算法，这种算法是目前所有圆周率算法中最快的一种，这个计算N位PI的公式比传统的BBQ算法要快47%。 　　2009年的最后一天，Fabr ice Bellard宣布另一重大突破：他用桌面电脑打破了由超级计算机保持的圆周率运算记录。这是一个壮举， 他将PI计算到了小数点后2.7万亿位！更令人惊讶的是， 他使用的不过是价格不到2000欧元的个人PC，仅用了116天，就计算出了PI的小数点后第2.7万亿位，超过了排名世界第47位的T2K Open超级计算机于2009年8月17日创造的世界纪录。新纪录比原纪录多出1200亿位，然而，他使用的这台桌面电脑的配置仅为：2.93GHz Core i7 CPU，6GB内存，7.5TB硬盘! 　　不过这次为了加快计算完成的速度保住排名第一的位置，Fabrice Bel lard使用了9台联网的电脑来对数据进行验证， 若使用一台电脑来验证计算结果的话， 则需要额外增加13天的计算时间。 　　Fabrice Bellard在圆周率方面的辉煌成就， 使他创造多次圆周率单一位计算的世界纪录（计算10的整次幂位） ， 也曾因此而登上《科学美国人》法文版。

You can’t perform that action at this time.