为什么在这种情况下float32比float64更准确?

时间:2019-07-12 04:16:23

标签: go

如果我运行以下Go代码:

fmt.Println(float32(0.1) + float32(0.2))
fmt.Println(float64(0.1) + float64(0.2))

输出为:

0.3
0.30000000000000004

似乎float32和的结果比float64和的结果更精确,为什么?我认为float64总是比float32更精确。我该如何决定选择哪一个才能获得最准确的结果?

1 个答案:

答案 0 :(得分:6)

不是。 fmt.Println只是使其看起来更加精确。 Println使用%g表示浮点数和复数。 The docs say ...

  

...的默认精度。%g是唯一标识该值所需的最小位数。

0.3足以标识float32。但是float64要精确得多,需要更多位数。

我们可以使用fmt.Printf%0.20g来强制两个数字显示相同的精度。

f32 := float32(0.1) + float32(0.2)
f64 := float64(0.1) + float64(0.2)

fmt.Printf("%0.20g\n", f32)
fmt.Printf("%0.20g\n", f64)

0.30000001192092895508
0.30000000000000004441

float64更精确。两者都不是精确的,因为这是浮点数的本质。

我们可以使用strconv.FormatFloat来查看这些数字的真实含义。

fmt.Println(strconv.FormatFloat(float64(f32), 'b', -1, 32))
fmt.Println(strconv.FormatFloat(f64, 'b', -1, 64))

10066330p-25
5404319552844596p-54

10066330 * 2^-255404319552844596 * 2^-54