英文:
Float Accuracy in Go
问题
这个问题是我之前提出的问题的后续问题。我收到的答案建议我使用Go的math.Big库。在这个问题中,我使用了这个库,但是效果不佳。
我试图使用Binet公式计算fib(100)。我使用了Go的Big.Float,但是没有成功。我只能得到大约10位小数的精度。请给予建议。
我试图避免使用循环/递归,因为我认为这些方法不会很好地扩展。因此,我尝试利用Binet公式。
// 当输入增加时,目前会产生不准确的结果。
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")
}
英文:
This question is a follow on from a previous question I asked. The answers I received suggested that I make use of the Go math.Big library. In this question I use the library but unfortunately to little effect.
I am trying to using the Binet formula to calculate fib(100). I am using
Go's Big.Float but without success. I get accuracy to about 10 decimal
places. Please advise.
I am trying to avoid loops/recursion as I think these approaches will
not scale well. Hence my attempt to leverage Binet's formula
// currently produces inaccurate results as the input increases.
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")
}
答案1
得分: 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))
}
输出结果为:
354224848179261915075
英文:
You are using IEEE 754 64-bit floating point.
In Go, to calculate fib(100)
accurately you could simply say:
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))
}
Output:
354224848179261915075
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论