Files
the-way-to-go_ZH_CN/eBook/09.4.md
2015-03-01 01:07:43 -05:00

2.2 KiB
Raw Blame History

精密计算和 big 包

202 我们知道有些时候通过编程的方式去进行计算是不精确的。如果你使用Go语言中的fload64类型进行浮点运算返回结果将精确到15位足以满足大多数的任务。当对超出in64或者uint64类型这样的大数进行计算时如果对精度没有要求float32或者float64可以胜任但如果对精度有严格要求的时候我们不能使用浮点数在内存中它们只能被近似的表示。

对于整数的高精度计算Go语言中提供了big包。其中包含了math包有用来表示大整数的big.Int和表示大有理数的big.Rat类型(可以表示为2/5或3.1416这样的分数,而不是无理数或π)。这些类型可以实现任意位类型的数字,只要内存足够大。缺点是更大的内存和处理开销使它们使用起来要比内置的数字类型慢很多。

大的整型数字是通过big.NewInt(n)来构造的其中n位int64类型整数。而大有理数是用过big.NewRat(N,D)方法构造.N(分子)和D(分母)都是int64型整数。因为Go语言不支持运算符重载所以所有大数字类型都有像是Add()和Mul()这样的方法。它们作用于作为receiver的整数和有理数,大多数情况下它们修改receiver并以receiver作为返回结果。因为没有必要创建big.Int类型的临时变量来存放中间结果所以这样的运算可通过内存链式存储。

示例 9.2 big.go

package main
import (
	"fmt"
	"math""
	"math/big"
)
func main() {
	// Here are some calculations with bigInts:
    im := big.NewInt(math.MaxInt64)
    in := im
    io := big.NewInt(1956)
    ip := big.NewInt(1)
    ip.Mul(im, in).Add(ip, im).Div(ip, io)
    fmt.Printf(“Big Int: %v\n”, ip)
    // Here are some calculations with bigInts:
    rm := big.NewRat(math.MaxInt64, 1956)
    rn := big.NewRat(-1956, math.MaxInt64)
    ro := big.NewRat(19, 56)
    rp := big.NewRat(1111, 2222)
    rq := big.NewRat(1, 1)
    rq.Mul(rm, rn).Add(rq, ro).Mul(rq, rp)
    fmt.Printf(“Big Rat: %v\n”, rq)
  }

输出结果:

Big Int: 43492122561469640008497075573153004
Big Rat: -37/112