精度的奇怪损失乘以大浮点数

时间:2018-09-04 07:12:36

标签: go

如果将字符串解析为f.SetString("0.001")之类的big.Float,然后将其相乘,我会发现精度下降。如果使用f.SetFloat64(0.001),则不会失去精度。即使执行strconv.ParseFloat("0.001", 64),然后调用f.SetFloat()也可以。

我在这里看到的完整示例:

https://play.golang.org/p/_AyTHJJBUeL

从这个问题扩展:https://stackoverflow.com/a/47546136/105562

1 个答案:

答案 0 :(得分:0)

输出的差异是由于float64IEEE-754 format)中以10为基数的浮点数的表示不精确,以及big.Float的默认精度和舍入。

查看以下简单代码进行验证:

fmt.Printf("%.30f\n", 0.001)
f, ok := new(big.Float).SetString("0.001")
fmt.Println(f.Prec(), ok)

以上内容的输出(在Go Playground上尝试):

0.001000000000000000020816681712
64 true

因此,我们看到的是float640.001并不完全是0.001,并且big.Float的默认精度是64。

如果您提高通过string值设置的数字的精度,则会看到相同的输出:

s := "0.001"
f := new(big.Float)
f.SetPrec(100)
f.SetString(s)
fmt.Println(s)
fmt.Println(BigFloatToBigInt(f))

现在输出也将相同(在Go Playground上尝试):

0.001
1000000000000000