numpy 如何在从float32转换为float时保持精度?

hmae6n7t  于 2023-04-19  发布在  其他
关注(0)|答案(2)|浏览(248)

我有一个numpy.float32对象,我想编码为JSON。问题是,当我转换到原生python float时,我失去了值的精度。
示例:

In [1]: import numpy as np
In [4]: np.float32(295.96).item()
Out[4]: 295.9599914550781

但是,如果我先转换为字符串,然后再转换为浮点数,则精度将保留。

In [3]: float(str(np.float32(295.96)))
Out[3]: 295.96

有没有一种方法可以保持我的精度,而不必先通过一个字符串?
为什么str(np.float32(295.96))似乎保持了精度,而np.float32(295.96).item()(或float(np.float32(295.96))np.asscalar(np.float32(295.96)))却没有?
注意:我不能假设精度总是.01。我需要保持数据的原始精度。

k5ifujac

k5ifujac1#

不可能在32位值中存储64位精度。在Python中,float是64位的(在C中称为double)。作为一个演示,64位浮点数的一切都很好:

>>> d = 295.6; dn = np.float64(d)
>>> (d, dn)
(295.6, 295.95999999999998)  # numpy prints out more digits than python
>>> d == dn  # but these are still the same
True
>>> d - dn
0.0

但是如果你尝试使用32位,你会降低精度

>>> d = 295.96; fn = np.float32(d)
>>> (d, fn)
(295.96, 295.95999)
>>> d == fn
False
>>> d - fn
8.5449218545363692e-06

为什么str(np.float32(295.96))似乎保持了精度
str(np.float32(295.96))看起来保持了精度,因为np.float32.__str__为了方便而舍入(以10为基数)。碰巧的是,四舍五入后,它与您在代码中键入的文本完全匹配。因此,它具有完全相同的值。

jbose2ul

jbose2ul2#

您错误地认为在控制台中看到的就是实际发生的情况。您看到的结果(即四舍五入)只为你=看控制台的人。不幸的是,这就是如何实现浮动的打印(IMO令人困惑)。
基础浮动始终正确,例如

In [4]: a = np.float32(295.96)
In [5]: a
Out[5]: 295.95999
In [6]: import json
In [7]: json.dumps(a.item())
Out[7]: '295.9599914550781'

相关问题