-1

I got a float64 value 43701.330694444441, after i call strconv.ParseFloat(v, 64) function, the result turn out to be 43701.33069444444. Anyone can solve this?

v := "43701.330694444441"

f, err := strconv.ParseFloat(v, 64)
if err != nil {
    return
}
fmt.Println(f) // it output 43701.33069444444, the tail '1' is missing.
peterSO
  • 158,998
  • 31
  • 281
  • 276
  • 1
    Possible duplicate of https://stackoverflow.com/q/21895756/13860 – Jonathan Hall Sep 29 '19 at 08:12
  • 1
    Possible duplicate of [Why are floating point numbers inaccurate?](https://stackoverflow.com/questions/21895756/why-are-floating-point-numbers-inaccurate) – torek Sep 29 '19 at 08:55
  • The "duplicate" links in the comments provide no information on how to get a precise floating-point value value in Go, since `strconv.ParseFloat(v, 64)` is not adequate. The links merely explain floating-point mathematics. – peterSO Sep 29 '19 at 14:23
  • You need more precision, please check https://stackoverflow.com/questions/46374304/dealing-with-floating-point-number-precision-in-go-arithmetic – Medeni Baykal Oct 09 '19 at 12:26
  • This question is perfectly fine. I was wondering too and found my answer here – Neifen Aug 02 '23 at 04:12

1 Answers1

5

The limitations of float64, 53-bit precision 64-bit IEEE 754 binary floating-point. For a more precise representation, use math/big type Float with more precision.

For example,

package main

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

func main() {
    v := "43701.330694444441"
    f1, err := strconv.ParseFloat(v, 64) // 53-bit precision
    fmt.Println(f1, err)
    f2, ok := big.NewFloat(0).SetPrec(53).SetString(v)
    fmt.Println(f2, ok)
    f3, ok := big.NewFloat(0).SetPrec(55).SetString(v)
    fmt.Println(f3, ok)
}

Playground: https://play.golang.org/p/8aVj-y83Mdp

Output:

43701.33069444444 <nil>
43701.33069444444 true
43701.330694444441 true
peterSO
  • 158,998
  • 31
  • 281
  • 276