Go中的浮动精度

Kev*_*vin 1 floating-accuracy go

这个问题是我提出的一个问题的后续问题.我收到的答案表明我使用了Go math.Big库.在这个问题中,我使用了库,但不幸的是效果不大.

我正在尝试使用Binet公式来计算fib(100).我正在使用Go的Big.Float但没有成功.我精确到小数点后10位.请指教.

我试图避免循环/递归,因为我认为这些方法不能很好地扩展.因此,我试图利用比奈的公式

//当前输入增加时会产生不准确的结果.

package main

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

func fib(n int) float64  {
    var sroot5 = new(big.Float).SetPrec(200).SetFloat64(2.236067977499789696409173668731276235440618359611525724270897)
    var phi = new(big.Float).SetPrec(200).SetFloat64(1.61803398874989484820458683436563811772030917980576286213544862)
    var minusPhi = new(big.Float).SetPrec(200).SetFloat64(-0.61803398874989484820458683436563811772030917980576)

    var fltP float64;
    fltP, _ = phi.Float64()

    var fltN float64;
    fltN, _ = minusPhi.Float64()

    var denom float64
    denom, _ = sroot5.Float64()

    // Magic fib formula (Binet) is:
    // (Phi ^ n - (-phi ^ n)) / sqrt(5)

    z := (math.Pow(fltP, float64(n)) - math.Pow(fltN, float64(n))) / denom 

    return math.Ceil(z) 

}

func main() {

    fib(100)

    fmt.Println(strconv.FormatFloat(fib(100), 'f', 0, 64))
    fmt.Println("true answer of fib(100) should be -> 354224848179261915075")

}
Run Code Online (Sandbox Code Playgroud)

pet*_*rSO 6

您正在使用IEEE 754 64位浮点.

在Go中,为了fib(100)准确计算,您可以简单地说:

package main

import (
    "fmt"
    "math/big"
)

func fib(n int) *big.Int {
    f := big.NewInt(0)
    a, b := big.NewInt(0), big.NewInt(1)
    for i := 0; i <= n; i++ {
        f.Set(a)
        a.Set(b)
        b.Add(f, b)
    }
    return f
}

func main() {
    fmt.Println(fib(100))
}
Run Code Online (Sandbox Code Playgroud)

输出:

354224848179261915075
Run Code Online (Sandbox Code Playgroud)

  • @Kevin计算斐波纳契数的最快方法是通过重复矩阵​​平方,如[here](https://en.wikipedia.org/wiki/Fibonacci_number#Matrix_form)所述.你真的不想弄乱浮点数,因为结果不精确. (3认同)