为了账号安全,请及时绑定邮箱和手机立即绑定

为什么这两个 float64 有不同的值?

为什么这两个 float64 有不同的值?

Go
BIG阳 2021-09-10 17:30:42
考虑以下两种情况:fmt.Println(912 * 0.01)fmt.Println(float64(912) * 0.01)(去游乐场链接)第二个打印 9.120000000000001,这实际上很好,我明白为什么会这样。但是,为什么第一行打印 9.12,最后没有 …01?Go 是否将两个无类型常量相乘并在编译时简单地将它们替换为 9.12 文字?
查看完整描述

2 回答

?
ABOUTYOU

TA贡献1812条经验 获得超5个赞

根据规格:

常量表达式总是精确求值;中间值和常量本身可能需要比语言中任何预先声明的类型支持的精度大得多的精度。

自从

912 * 0.01

是一个常量表达式,它被精确地计算。因此,写作fmt.Println(912 * 0.01)与写作具有相同的效果fmt.Println(9.12)。当您固定912到 时float64,浮点乘法的另一个操作数也隐式固定到float64。因此,表达式的float64(912) * 0.01行为类似于float64(912) * float64(0.01)。0.01 在 a 中不能完全表示float64,因此精度在与第一个示例float64(912 * 0.01)中的参数中出现的表达式不同的地方丢失fmt.Println(),解释了不同的结果。


查看完整回答
反对 回复 2021-09-10
?
当年话下

TA贡献1890条经验 获得超9个赞

输出不同的原因是在第一种情况下912 * 0.01是任意精度的2个无类型常量值的乘法,并且只有float64在将值传递给时才将结果转换为Println()

在第二种情况下,float64(912) * 0.01首先912转换为float64,然后将无类型常量0.01转换为float64并且这两个值float64相乘,这不是任意精度,并且不会给出确切的结果。

笔记:

在第一种情况下,结果将float64在传递给 时转换为Println()

fmt.Printf("%T %v\n", 912 * 0.01, 912 * 0.01)

输出:

float64 9.12


查看完整回答
反对 回复 2021-09-10
  • 2 回答
  • 0 关注
  • 201 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信