gpt4 book ai didi

Golang 浮点精度 float32 与 float64

转载 作者:IT老高 更新时间:2023-10-28 13:03:14 27 4
gpt4 key购买 nike

我写了一个程序来演示 Go 中的浮点错误:

func main() {
a := float64(0.2)
a += 0.1
a -= 0.3
var i int
for i = 0; a < 1.0; i++ {
a += a
}
fmt.Printf("After %d iterations, a = %e\n", i, a)
}

打印出来:

After 54 iterations, a = 1.000000e+00

这与用 C 编写的同一程序的行为相匹配(使用 double 类型)

但是,如果改为使用 float32,程序就会陷入无限循环!如果您修改 C 程序以使用 float 而不是 double,它会打印

After 27 iterations, a = 1.600000e+00

为什么Go程序在使用float32时输出和C程序不一样?

最佳答案

使用 math.Float32bitsmath.Float64bits ,您可以看到 Go 如何将不同的十进制值表示为 IEEE 754 二进制值:

Playground :https://play.golang.org/p/ZqzdCZLfvC

结果:

float32(0.1): 00111101110011001100110011001101
float32(0.2): 00111110010011001100110011001101
float32(0.3): 00111110100110011001100110011010
float64(0.1): 0011111110111001100110011001100110011001100110011001100110011010
float64(0.2): 0011111111001001100110011001100110011001100110011001100110011010
float64(0.3): 0011111111010011001100110011001100110011001100110011001100110011

如果你 convert these二进制表示为十进制值并执行循环,您可以看到对于 float32,a 的初始值将是:

0.20000000298023224
+ 0.10000000149011612
- 0.30000001192092896
= -7.4505806e-9

一个永远不会等于 1 的负值。

那么,为什么 C 的行为会有所不同?

如果您查看二进制模式(并且稍微了解如何表示二进制值),您会发现 Go 会舍入最后一位,而我假设 C 只是裁剪它。

因此,从某种意义上说,虽然 Go 和 C 都不能准确地表示 float 中的 0.1,但 Go 使用最接近 0.1 的值:

Go:   00111101110011001100110011001101 => 0.10000000149011612
C(?): 00111101110011001100110011001100 => 0.09999999403953552

编辑:

我发布了 a question about how C handles float constants ,从答案看来,C 标准的任何实现都允许这样做。您尝试使用的实现与 Go 不同。

关于Golang 浮点精度 float32 与 float64,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22337418/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com