为什么在将float32转换为float64时会丢失精度?

May*_*tel 7 floating-point precision go

虽然在Go中丢失了将float32数转换为float64的精度.例如,将359.9转换为float64会生成359.8999938964844.如果float32可以精确存储,为什么float64会丢失精度?

示例代码:

package main

import (
    "fmt"
)

func main() {
    var a float32 = 359.9
    fmt.Println(a)
    fmt.Println(float64(a))
}
Run Code Online (Sandbox Code Playgroud)

试试 Playground

小智 10

永远不会从一个转换时丢失精度float(即FLOAT32)到double(float64).前者必须是后者的一个子集.

它更多地与输出格式化程序的默认精度有关.

最接近的IEEE754 float到359.9是

359.899993896484375
Run Code Online (Sandbox Code Playgroud)

最接近的IEEE754 double到359.9是

359.8999999999999772626324556767940521240234375
Run Code Online (Sandbox Code Playgroud)

最近的IEEE754 double到359.899993896484375是

359.899993896484375
Run Code Online (Sandbox Code Playgroud)

(即是相同的;由于我已经提到的子集规则).

所以你可以看到它float64(a)float64(359.899993896484375)它是一样的359.899993896484375.这解释了输出,虽然您的格式化程序正在舍入最后的2位数.

  • 在这里,我认为这个答案是完美的.难道你没有看到它是由于将359.9转换为浮点数359.899993896484375,将其转换为float64没有任何效果,你只打印它? (2认同)

Pla*_*ato 6

这有助于我理解@ FaceyMcFaceFace的答案:

var a float32 = math.Pi
fmt.Println(a)
fmt.Println(float64(a))
fmt.Println(float64(math.Pi))

3.1415927
3.1415927410125732
3.141592653589793
Run Code Online (Sandbox Code Playgroud)

https://play.golang.org/p/-bAQLqjlLG