使用math包和math/big包处理数字类型
发布者:admin 发表于:444天前 阅读数:505 评论:0

实践

1.创建math.go:

package math

import (
    "fmt"
    "math"
)

// Examples 演示了math包的基本应用
func Examples() {
    //开平方示例
    i := 25

    // i 是整型,所以需要转型
    result := math.Sqrt(float64(i))

    // 25开方结果是 5
    fmt.Println(result)

    // ceil能够获取大于或等于输入值的最小整数值
    result = math.Ceil(9.5)
    fmt.Println(result)

    // floor能够获取大于或等于输入值的最大整数值
    result = math.Floor(9.5)
    fmt.Println(result)

    // math包同样提供了常用的常数
    fmt.Println("Pi:", math.Pi, "E:", math.E)
}

2.创建fib.go:

package math

import "math/big"

// 全局变量
var memoize map[int]*big.Int

func init() {
    // 初始化map
    memoize = make(map[int]*big.Int)
}

// Fib打印斐波纳契序列的第n个数字,它将返回1以表示任何<0 ...它是递归计算并使用big.Int因为int64会快速溢出
func Fib(n int) *big.Int {
    if n < 0 {
        return nil
    }

    // 基础条件
    if n < 2 {
        memoize[n] = big.NewInt(1)
    }

    // 检查我们是否存储它之前进行了计算
    if val, ok := memoize[n]; ok {
        return val
    }

    // 使用map存储然后添加前2个fib值
    memoize[n] = big.NewInt(0)
    memoize[n].Add(memoize[n], Fib(n-1))
    memoize[n].Add(memoize[n], Fib(n-2))

    return memoize[n]
}

3.建立main.go:

package main

import (
    "fmt"

    "github.com/agtorre/go-cookbook/chapter3/math"
)

func main() {
    math.Examples()

    for i := 0; i < 10; i++ {
        fmt.Printf("%v ", math.Fib(i))
    }
    fmt.Println()
}

4.这会输出:

5
10
9
Pi: 3.141592653589793 E: 2.718281828459045
1 1 2 3 5 8 13 21 34 55 

说明

math包使得在Go中执行复杂的数学运算成为可能。本节以执行复杂的浮点操作并根据需要在类型之间进行转换。 值得注意的是,即使使用float64,某些浮点数仍可能存在舍入错误,下一节演示了一些处理此问题的技巧。

math/big部分展示了一个递归的Fibonacci序列。如果你修改main.go循环远远超过10次,如果使用它而不是big.Int,程序将很快溢出int64。这个包还有一些辅助函数,可以将big类型转换为其他类型。