Float Accuracy in Go

huangapple go评论114阅读模式
英文:

Float Accuracy in Go

问题

这个问题是我之前提出的问题的后续问题。我收到的答案建议我使用Go的math.Big库。在这个问题中,我使用了这个库,但是效果不佳。

我试图使用Binet公式计算fib(100)。我使用了Go的Big.Float,但是没有成功。我只能得到大约10位小数的精度。请给予建议。

我试图避免使用循环/递归,因为我认为这些方法不会很好地扩展。因此,我尝试利用Binet公式。

  1. // 当输入增加时,目前会产生不准确的结果。
  2. package main
  3. import (
  4. "fmt"
  5. "math/big"
  6. "math"
  7. "strconv"
  8. )
  9. func fib(n int) float64 {
  10. var sroot5 = new(big.Float).SetPrec(200).SetFloat64(2.236067977499789696409173668731276235440618359611525724270897)
  11. var phi = new(big.Float).SetPrec(200).SetFloat64(1.61803398874989484820458683436563811772030917980576286213544862)
  12. var minusPhi = new(big.Float).SetPrec(200).SetFloat64(-0.61803398874989484820458683436563811772030917980576)
  13. var fltP float64;
  14. fltP, _ = phi.Float64()
  15. var fltN float64;
  16. fltN, _ = minusPhi.Float64()
  17. var denom float64
  18. denom, _ = sroot5.Float64()
  19. // Magic fib formula (Binet) is:
  20. // (Phi ^ n - (-phi ^ n)) / sqrt(5)
  21. z := (math.Pow(fltP, float64(n)) - math.Pow(fltN, float64(n))) / denom
  22. return math.Ceil(z)
  23. }
  24. func main() {
  25. fib(100)
  26. fmt.Println(strconv.FormatFloat(fib(100), 'f', 0, 64))
  27. fmt.Println("true answer of fib(100) should be -> 354224848179261915075")
  28. }
英文:

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.

  1. package main
  2. import (
  3. "fmt"
  4. "math/big"
  5. "math"
  6. "strconv"
  7. )
  8. func fib(n int) float64 {
  9. var sroot5 = new(big.Float).SetPrec(200).SetFloat64(2.236067977499789696409173668731276235440618359611525724270897)
  10. var phi = new(big.Float).SetPrec(200).SetFloat64(1.61803398874989484820458683436563811772030917980576286213544862)
  11. var minusPhi = new(big.Float).SetPrec(200).SetFloat64(-0.61803398874989484820458683436563811772030917980576)
  12. var fltP float64;
  13. fltP, _ = phi.Float64()
  14. var fltN float64;
  15. fltN, _ = minusPhi.Float64()
  16. var denom float64
  17. denom, _ = sroot5.Float64()
  18. // Magic fib formula (Binet) is:
  19. // (Phi ^ n - (-phi ^ n)) / sqrt(5)
  20. z := (math.Pow(fltP, float64(n)) - math.Pow(fltN, float64(n))) / denom
  21. return math.Ceil(z)
  22. }
  23. func main() {
  24. fib(100)
  25. fmt.Println(strconv.FormatFloat(fib(100), 'f', 0, 64))
  26. fmt.Println("true answer of fib(100) should be -> 354224848179261915075")
  27. }

答案1

得分: 6

你正在使用IEEE 754 64位浮点数

在Go语言中,要准确计算fib(100),你可以简单地使用以下代码:

  1. package main
  2. import (
  3. "fmt"
  4. "math/big"
  5. )
  6. func fib(n int) *big.Int {
  7. f := big.NewInt(0)
  8. a, b := big.NewInt(0), big.NewInt(1)
  9. for i := 0; i <= n; i++ {
  10. f.Set(a)
  11. a.Set(b)
  12. b.Add(f, b)
  13. }
  14. return f
  15. }
  16. func main() {
  17. fmt.Println(fib(100))
  18. }

输出结果为:

  1. 354224848179261915075
英文:

You are using IEEE 754 64-bit floating point.

In Go, to calculate fib(100) accurately you could simply say:

  1. package main
  2. import (
  3. &quot;fmt&quot;
  4. &quot;math/big&quot;
  5. )
  6. func fib(n int) *big.Int {
  7. f := big.NewInt(0)
  8. a, b := big.NewInt(0), big.NewInt(1)
  9. for i := 0; i &lt;= n; i++ {
  10. f.Set(a)
  11. a.Set(b)
  12. b.Add(f, b)
  13. }
  14. return f
  15. }
  16. func main() {
  17. fmt.Println(fib(100))
  18. }

Output:

  1. 354224848179261915075

huangapple
  • 本文由 发表于 2015年8月22日 23:34:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/32157833.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定