【问题标题】:number format is different in linux and windows version of pycharmlinux和windows版本的pycharm数字格式不同
【发布时间】:2018-04-26 12:12:34
【问题描述】:

我在 Linux 的 PyCharm 中使用了一个 python 代码,数字的格式是 -91.35357。当我在 Windows 格式的 PyCharm 中使用相同的代码时 -91.35356999999999。问题是值包含在我需要打开的文件名中(并且要打开的文件列表很长)。

任何人都知道可能的解释和热修复它?

【问题讨论】:

  • 在文件名中包含浮点数是一个非常糟糕的主意。如果您想要一致的表示,请明确说明应该显示多少小数位。
  • 除非您向我们展示代码,否则我们无能为力。 minimal reproducible example
  • @jonrshape:文件名中必须有浮点,因为它指的是数据位置的纬度和经度。此外,每个位置的纬度或经度小数位数也不相同。

标签: python pycharm number-formatting


【解决方案1】:

浮动

永远记住浮点数的精度是有限的。如果您考虑一下,如果您将存储限制为 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 位。

【讨论】:

  • "浮点数使用默认架构字长实现。"这是错误的。 32 位机器和 64 位机器都使用 C double。在绝大多数机器(32 位 64 位)上,这是 IEEE 754 binary64 类型。
  • @jjmontes:感谢您的解释,numpy.float32(n) 可以提供帮助
【解决方案2】:

Linux 上的 PyCharm 只是对大浮点数进行四舍五入。将其四舍五入到最接近的 6 或 7 可以解决您的问题,但不要使用这些作为文件名。

在这两种情况下保持你的代码不变,他们可以有很多解释:

1) 32 位处理器处理浮点数的方式与 64 位处理器不同。

2) Linux 和 Windows 的 PyCharm 对浮点的行为不同,我们无法准确确定,可能是 Windows 的 PyCharm 得到了更好的优化。

编辑 1

第 1 点说明

在 32 位处理器上,所有操作实际上都是在内部以 80 位精度完成的。精度实际上只是决定了这些位中有多少存储在内存中。这就是为什么不同的优化设置会稍微改变结果的部分原因:它们将舍入量从 80 位更改为 32 位或 64 位。

编辑 2

您可以使用哈希映射将数据保存在文件中,然后将它们映射到坐标上。 示例:

# variable = {(long,lat):"<random_file_name>"}
cordinates_and_file ={(-92.45453534,-87.2123123):"AxdwaWAsdAwdz"}

【讨论】:

  • @NoorAliJafri:文件名中必须有浮点,因为它指的是数据位置的纬度和经度。此外,每个位置的纬度或经度小数位数也不相同。但是,在 Linux 和 Windows 格式中,纬度和经度的数字都是 float64 。
  • 我会建议你对某些问题使用哈希映射,例如:cordinates_and_file ={(-92.45453534,-87.2123123):"AxdwaWAsdAwdz"}
  • 我认为出于同样的原因,您不应该使用浮点数作为散列键。
  • 但总比按照你的浮动结果认真地保留整个文件名要好。 :D 我知道这不是正确的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-30
  • 1970-01-01
相关资源
最近更新 更多