How to store a big float64 in a string without overflow?

我的梦境 提交于 2019-12-11 19:50:04

问题


func main() {
        target := 20190201518310870.0
        fmt.Println(int64(target))
        z3 := big.NewInt(int64(target))
        fmt.Println(z3)
}

The result is 20190201518310872

How do I convert it and not make overflow?


回答1:


The problem is that even your input target number is not equal to the constant you assign to it.

The float64 type uses the double-precision floating-point format (IEEE 754) to store the number, which has finite bits to utilize (64 bits in total, but only 53 bits are used to store the significand). This means it can roughly store ~16 digits, but your input number has 17, so it will be rounded to the nearest representable float64.

If you print target, you will see the exact number that is "transfered" to big.Int:

target := 20190201518310870.0
fmt.Printf("%f\n", target)

Outputs (try it on the Go Playground):

20190201518310872.000000

Note that it works if the input constant "fits" into float64:

target := 20190201518310.0
fmt.Printf("%f\n", target)
fmt.Println(int64(target))
z3 := big.NewInt(int64(target))
fmt.Println(z3)

Outputs (try it on the Go Playground):

20190201518310.000000
20190201518310
20190201518310

If you need to work with big numbers exactly such as 20190201518310870.0, you have to use another type to store it in the first place, e.g. string, big.Int or big.Float, but not float64.

For example:

target := "20190201518310870"
fmt.Println(target)
z3, ok := big.NewInt(0).SetString(target, 10)
fmt.Println(z3, ok)

Output (try it on the Go Playground):

20190201518310870
20190201518310870 true


来源:https://stackoverflow.com/questions/54477761/how-to-store-a-big-float64-in-a-string-without-overflow

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!