Go:为啥从 float64 转换为 float32 并返回会导致值发生变化? [复制]
Posted
技术标签:
【中文标题】Go:为啥从 float64 转换为 float32 并返回会导致值发生变化? [复制]【英文标题】:Go: Why does converting from a float64 to a float32 and back cause a change to the value? [duplicate]Go:为什么从 float64 转换为 float32 并返回会导致值发生变化? [复制] 【发布时间】:2021-03-19 22:42:18 【问题描述】:有没有办法在不改变数据的情况下处理这种转换?
f := float64(-3942.2)
fmt.Println(float64(float32(f))) // = -3942.199951171875
找回-3942.2
的唯一方法是将其重铸为float32
:
fmt.Println(float32(float64(float32(f)))) // = -3942.2
https://play.golang.org/p/ReIefOPEaoz
编辑:
这不是格式问题:
f := float64(-3942.2)
fmt.Println(f == float64(float32(f))) // false
编辑2:
fmt.Println(f) // -3942.2
fmt.Println(float32(f) == float32(float64(float32(f)))) // true
【问题讨论】:
【参考方案1】:float32
的精度低于float64
。两种类型都不能准确表示实数 -3942.2,但float64
更接近。
当您转换为float32
时,该值必须四舍五入到可表示为float32
的最接近的值。丢失的信息无法恢复;转换回float64
不会重现原始值。
第三次转换回float32
,如float32(float64(float32(f)))
,不会恢复原始值。它看起来只是因为fmt.Println
的默认舍入行为。默认情况下,fmt.Println
将打印具有足够位数的浮点值,以将它们与其他相同类型的值区分开来。
因为float64
具有更高的精度,所以区分float64(float32(f))
与其他float64
值所需的小数位数大于区分float32(f)
或float32(float64(float32(f)))
与其他@987654336 所需的小数位数@值。
【讨论】:
【参考方案2】:它们是相同的值,只是 fmt.Println
的默认格式显示其中一个的有效数字较低,而另一个则不显示。
比较
https://play.golang.org/p/hJs-5Oz_YlL
package main
import (
"fmt"
)
func main()
f := float64(-3942.2)
fmt.Printf("float64(float32(f)):\t\t%.20f\n", float64(float32(f)))
fmt.Printf("float32(float64(float32(f))):\t%.20f\n", float32(float64(float32(f)))) // = -3942.2
// float64(float32(f)): -3942.19995117187500000000
// float32(float64(float32(f))): -3942.19995117187500000000
【讨论】:
它们的值不同fmt.Println(float64(float32(f)) == f) // false
@Chance 在您的原始帖子中,您从不直接打印 f 的值(不将其转换一次为 float32)-3942.2 不能完全存储在 float32 中,也不能在 float64 中,但在 float64 中,您将有更接近的近似值(更多数字),所以这就是它们不相等的原因。
@mgagnon play.golang.org/p/7q0Yq26OCBL fmt.Println(f) // -3942.2
fmt.Println(float32(f) == float32(float64(float32(f))))
// 是的
@Chance 这就是我所期望的。一旦在 float32 中转换,它就无法恢复丢失的精度。
@Chance 我的回答解释了 original 问题的输出差异。不,比较float64(float32(f)) == f
是没有意义的,因为你会失去精度。但是在你丢失它之后(就像在问题的 v1 中一样) - 它们是相同的值。来自原始问题:fmt.Println(float32(f) == float32(float64(float32(f)))) // true
(如预期)以上是关于Go:为啥从 float64 转换为 float32 并返回会导致值发生变化? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Pandas 将我的 numpy float32 强制转换为 float64?