Go 中的浮点精度与 Python
Floating point precision in Go vs Python
刚开始学go,教程给出了这个例子:
myNum := 0.1234
// this evaluates to false
if myNum == math.Pow(math.Sqrt(myNum), 2) {
println(true)
} else {
println(false)
}
// this evalues to true
if math.Abs(myNum/math.Pow(math.Sqrt(myNum), 2)-1) < 0.000000000000001 {
println(true)
} else {
println(false)
}
现在据说前者的计算结果不为真,因为浮点数是十进制值的近似值。但是,为什么……完全行不通?
完全相同的示例在 python 中确实有效,所以我有点困惑。令我烦恼的是,对于像这样的一些 'simple' 算术,计算机应该 excel,我们必须采取这些额外的预防措施
a = 0.12345
a == math.sqrt(a ** 2) # evaluates to True
Now it was said that the former doesn't evaluate to true because floats are approximations of decimal values. But why ... exactly doesn't that work?
在我相信 Go 使用的 IEEE-754 二进制 64 格式中,最接近 .1234 的可表示值是 0.12339999999999999580335696691690827719867229461669921875 (8891907104280307/2[=18==]56)。[=21]与其平方根最接近的可表示值是 0.351283361405005933875145274214446544647216796875 (6328158462100160/254)。最接近其平方的可表示值是 0.123400000000000009681144774731365032494068145751953125 (8891907104280308/256).
发生的情况是每个操作都必须将其结果四舍五入为可表示的值,从而在此过程中失去了一些准确性。在这种情况下,使用二进制或浮点数甚至都不是问题:平方根通常不能用有限的数字格式表示,因此它们必然会失去准确性。
The exact same example does work in python…
Python 文档没有精确指定浮点运算。实施各不相同。您可能需要指定特定的实现才能得到答案。
刚开始学go,教程给出了这个例子:
myNum := 0.1234
// this evaluates to false
if myNum == math.Pow(math.Sqrt(myNum), 2) {
println(true)
} else {
println(false)
}
// this evalues to true
if math.Abs(myNum/math.Pow(math.Sqrt(myNum), 2)-1) < 0.000000000000001 {
println(true)
} else {
println(false)
}
现在据说前者的计算结果不为真,因为浮点数是十进制值的近似值。但是,为什么……完全行不通?
完全相同的示例在 python 中确实有效,所以我有点困惑。令我烦恼的是,对于像这样的一些 'simple' 算术,计算机应该 excel,我们必须采取这些额外的预防措施
a = 0.12345
a == math.sqrt(a ** 2) # evaluates to True
Now it was said that the former doesn't evaluate to true because floats are approximations of decimal values. But why ... exactly doesn't that work?
在我相信 Go 使用的 IEEE-754 二进制 64 格式中,最接近 .1234 的可表示值是 0.12339999999999999580335696691690827719867229461669921875 (8891907104280307/2[=18==]56)。[=21]与其平方根最接近的可表示值是 0.351283361405005933875145274214446544647216796875 (6328158462100160/254)。最接近其平方的可表示值是 0.123400000000000009681144774731365032494068145751953125 (8891907104280308/256).
发生的情况是每个操作都必须将其结果四舍五入为可表示的值,从而在此过程中失去了一些准确性。在这种情况下,使用二进制或浮点数甚至都不是问题:平方根通常不能用有限的数字格式表示,因此它们必然会失去准确性。
The exact same example does work in python…
Python 文档没有精确指定浮点运算。实施各不相同。您可能需要指定特定的实现才能得到答案。