• golang 的 math/big 进行


    进行高进度运算的时候unint64已经无法满足需求,这个时候大家可以采用math.big库来进行高进度计算,下面以计算第10000位的菲波纳切数来展示big的用法,代码如下:

    package main
    
    import (
            "fmt"
            "math/big"
            "time"
    )
    
    const LIM = 10000 //求第10000位的费布拉切数
    
    var fibs [LIM]*big.Int //使用数组保存计算出来的费布拉切数的指针
    
    func main() {
            result := big.NewInt(0)
            start := time.Now()
            for i := 0; i < LIM; i++ {
                    result = fibonacci(i)
                    if i == LIM-1 {
                            fmt.Printf("fibonacci(%d) is: %d
    ", i, result)
                    }
            }
    
            fmt.Println(result)
            fmt.Printf("%T
    ", result)
            end := time.Now()
            delta := end.Sub(start)
            fmt.Printf("longCalculation took this amount of time: %s
    ", delta)
    }
    
    func fibonacci(n int) (res *big.Int) {
            if n <= 1 {
                    res = big.NewInt(1)
            } else {
                    temp := new(big.Int)
                    res = temp.Add(fibs[n-1], fibs[n-2])
            }
            fibs[n] = res
            return
    }

    计算结果正确,但是使用这个方法计算费布拉切不仅耗时而且占用太多的内存,可以定义两个变量去保存最近的前两个结果,这个就不用占用太多的内存,这样的话求第10000的费布拉切数的耗时可以降很多,如果还想将耗时降低的话,可以使用矩阵和快递幂运算,这样就可以将耗时降到us级别!

    Go语言的big包实现大整数运算
        // bigint project main.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
    ", ip)  
            iq := big.NewInt(10000)  
            ip.Mod(ip, iq)  
            fmt.Printf("Big Int: %v
    ", ip)  
        }  

    程序说明:

    1.math包中包含有各种功能函数,包括最大的整数math.MaxInt64

    2.math/big包可以用于大整数计算

    3.大整数可以使用"%v"格式输出

    另外,显式初始化一个大数只能到上限math.MaxInt64,如果想设置比这还大的数,则只能使用如下方法,即从byte到big int:

    Convert byte array to big.Int

    import "math/big"
    
    z := new(big.Int)
    z.SetBytes(byteSliceHere)

    or:

    func Base64ToInt(s string) (*big.Int, error) {
        data, err := base64.StdEncoding.DecodeString(s)
        if err != nil {
            return nil, err
        }
        i := new(big.Int)
        i.SetBytes(data)
        return i, nil
    }

    Convert String to big.Int

    使用 math/big 的内置函数:

    func (z *Int) SetString(s string, base int) (*Int, bool)

    示例:

    package main
    
    import (
        "fmt"
        "math/big"
    )
    
    func main() {
        n := new(big.Int)
        n, ok := n.SetString("314159265358979323846264338327950288419716939937510582097494459", 10)
        if !ok {
            fmt.Println("SetString: error")
            return
        }
        fmt.Println(n)
    }

    Convert a bigint to a string in Go :

    bigint := big.NewInt(123)
    bigstr := bigint.String()
  • 相关阅读:
    django model:auto_now_add 和 auto_now
    算法(2):数据结构
    Flask(2):登陆验证
    Flask(1):基本示例、配置文件、路由、请求和响应、模板渲染
    linux基础
    算法(1):查找&排序
    利用dispatch_once创建单例
    UIScrollView的属性总结
    ios开发 UITableViewController
    [深入浅出Cocoa]详解键值观察(KVO)及其实现机理
  • 原文地址:https://www.cnblogs.com/welhzh/p/8981096.html
Copyright © 2020-2023  润新知