为什么这两个 float64 有不同的值?
Why do these two float64s have different values?
考虑这两种情况:
fmt.Println(912 * 0.01)
fmt.Println(float64(912) * 0.01)
第二个打印9.120000000000001,其实没问题,I understand why that is happening。
但是,为什么第一行打印的是 9.12,而末尾没有 …01? Go 是否将两个无类型常量相乘并在编译时简单地用 9.12 文字替换它们?
输出不同的原因是第一种情况下 912 * 0.01
是任意精度的 2 个无类型常量值的乘积,当值传递给 Println()
。 (有关详细信息,请参阅语言规范的 Constant expressions 部分。)
第二种情况float64(912) * 0.01
先把912
转成float64
,再把无类型常量0.01
转成float64
这两个值float64
相乘,这不是任意精度,不会给出准确的结果。
注:
在第一种情况下,当传递给 Println()
:
时,结果将被转换为 float64
fmt.Printf("%T %v\n", 912 * 0.01, 912 * 0.01)
输出:
float64 9.12
根据spec:
Constant expressions are always evaluated exactly; intermediate values and the constants themselves may require precision significantly larger than supported by any predeclared type in the language.
从
开始
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 在 float64
中不能完全表示,因此精度在与第一个示例中 fmt.Println()
的参数中出现的表达式 float64(912 * 0.01)
不同的地方丢失,解释了不同的结果.
考虑这两种情况:
fmt.Println(912 * 0.01)
fmt.Println(float64(912) * 0.01)
第二个打印9.120000000000001,其实没问题,I understand why that is happening。
但是,为什么第一行打印的是 9.12,而末尾没有 …01? Go 是否将两个无类型常量相乘并在编译时简单地用 9.12 文字替换它们?
输出不同的原因是第一种情况下 912 * 0.01
是任意精度的 2 个无类型常量值的乘积,当值传递给 Println()
。 (有关详细信息,请参阅语言规范的 Constant expressions 部分。)
第二种情况float64(912) * 0.01
先把912
转成float64
,再把无类型常量0.01
转成float64
这两个值float64
相乘,这不是任意精度,不会给出准确的结果。
注:
在第一种情况下,当传递给 Println()
:
float64
fmt.Printf("%T %v\n", 912 * 0.01, 912 * 0.01)
输出:
float64 9.12
根据spec:
Constant expressions are always evaluated exactly; intermediate values and the constants themselves may require precision significantly larger than supported by any predeclared type in the language.
从
开始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 在 float64
中不能完全表示,因此精度在与第一个示例中 fmt.Println()
的参数中出现的表达式 float64(912 * 0.01)
不同的地方丢失,解释了不同的结果.