如何在字符串中存储一个大的float64而不会溢出?

时间:2019-02-01 10:38:46

标签: go overflow transfer

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

结果是20190201518310872

我该如何转换而不溢出?

1 个答案:

答案 0 :(得分:3)

问题在于,即使您输入的target号也不等于您为其分配的常数。

float64类型使用double-precision floating-point format(IEEE 754)存储数字,该数字具有有限的位可使用(总共64位,但是仅使用53位存储有效数字)。这意味着它可以大致存储约16位数字,但是您输入的数字有17位,因此将四舍五入到最接近的可表示float64

如果打印target,您将看到“转移”到big.Int的确切数字:

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

输出(在Go Playground上尝试):

20190201518310872.000000

请注意,如果输入常量“适合” float64

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

输出(在Go Playground上尝试):

20190201518310.000000
20190201518310
20190201518310

如果您需要使用完全像20190201518310870.0这样的大数,则必须使用另一种类型将其存储在第一位,例如stringbig.Intbig.Float,但不是float64

例如:

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

输出(在Go Playground上尝试):

20190201518310870
20190201518310870 true