浮动
永远记住浮点数的精度是有限的。如果您考虑一下,如果您将存储限制为 32 位或 64 位(或任何其他数字),必须限制您表示数字的精确度。
在 Python 中
Python 只提供一种浮点类型。浮点数通常使用 64 位实现,但它们在一个 Python 二进制文件中可能是 64 位,在另一个二进制文件中可能是 32 位,因此您不能真正依赖它(但是,请参阅下面的@Mark Dickinson 评论)。
让我们测试一下。但请注意,由于 Python 不提供 float32 和 float64 替代方案,我们将使用不同的库 numpy 来为我们提供这些类型和操作:
>>> n = 1.23456789012345678901234567890
>>> n
1.2345678901234567
>>> numpy.float64(n)
1.2345678901234567
>>> numpy.float32(n)
1.2345679
在这里我们可以看到 Python 在我的计算机中将变量处理为 float64。这已经截断了我们引入的数字(因为 float64 只能处理这么多的精度)。
当我们使用 float32 时,精度会进一步降低,并且由于截断,我们可以表示的最接近的数字略有不同。
结论
浮点分辨率是有限的。此外,一些操作在不同的架构中表现不同。
即使您使用一致的浮点大小,也不是所有数字都可以表示,并且操作会累积截断错误。
将一个浮点数与另一个浮点数进行比较应考虑可能的误差范围。不要使用float_a == float_b,而是使用abs(float_a - float_b) < error_margin。
依赖浮点表示总是一个坏主意。 Python 有时会使用科学记数法:
>>> a = 0.0000000001
>>> str(a)
'1e-10'
您可以获得一致的舍入近似值(即用于文件名),但请记住,存储和表示是不同的东西。这个其他线程可以帮助你:Limiting floats to two decimal points
一般来说,我建议不要在文件名中使用浮点数或作为任何其他类型的标识符。
纬度/经度
float32 数字的精度不足以表示纬度/经度对中的第 5 位和第 6 位十进制数字(取决于整数部分是一位、两位还是三位)。
如果您想了解实际情况,请查看此页面并测试您的一些数字:https://www.h-schmidt.net/FloatConverter/IEEE754.html
代表
请注意,Python 在表示浮点值时会对其进行四舍五入:
>>> lat = 123.456789
>>> "{0:.6f}".format(lat)
'123.456789'
>>> "{0:.5f}".format(lat)
'123.45679'
如上所述,纬度/经度不能用float32正确表示到小数点后6位,此外,截断的float值在Python表示时会四舍五入:
>>> lat = 123.456789
>>> lat
123.456789
>>> "{0:.5f}".format(numpy.float64(lat))
'123.45679'
>>> "{0:.5f}".format(numpy.float32(lat))
'123.45679'
>>> "{0:.6f}".format(numpy.float32(lat))
'123.456787'
如您所见,float32 数字的四舍五入版本与小数点后第 5 位的原始数字不匹配。但也做了四舍五入到 float64 数的小数点后 5 位。