gpt4 book ai didi

Python/numpy 浮点文本精度

转载 作者:行者123 更新时间:2023-11-28 19:37:42 25 4
gpt4 key购买 nike

假设我有一些 32 位和 64 位浮点值:

>>> import numpy as np
>>> v32 = np.array([5, 0.1, 2.4, 4.555555555555555, 12345678.92345678635],
dtype=np.float32)
>>> v64 = np.array([5, 0.1, 2.4, 4.555555555555555, 12345678.92345678635],
dtype=np.float64)

我想将这些值序列化为文本而不丢失精度(或者至少非常接近于不丢失精度)。我认为这样做的规范方法是使用 repr:

>>> map(repr, v32)
['5.0', '0.1', '2.4000001', '4.5555553', '12345679.0']
>>> map(repr, v64)
['5.0', '0.10000000000000001', '2.3999999999999999', '4.5555555555555554',
'12345678.923456786']

但我想让表示尽可能紧凑以最小化文件大小,所以如果像 2.4 这样的值在没有额外小数的情况下得到序列化,那就太好了。是的,我知道那是它们实际的浮点表示,但 %g 似乎能够解决这个问题:

>>> ('%.7g ' * len(v32)) % tuple(v32)
'5 0.1 2.4 4.555555 1.234568e+07 '
>>> ('%.16g ' * len(v32)) % tuple(v64)
'5 0.1 2.4 4.555555555555555 12345678.92345679 '

我的问题是:以这种方式使用 %g 安全吗? .7.16 的值是否正确,精度不会丢失?

最佳答案

Python 2.7 及更高版本已经有一个智能的 repr 实现,用于将 0.1 打印为 0.1 的 float 。选择简要输出优先于其他候选者,例如 0.10000000000000001,因为它是那个特定数字的最短表示,在回读时往返到完全相同的浮点值进入 Python。要使用此算法,请先将 64 位 float 转换为实际的 Python float ,然后再将它们传递给 repr:

>>> map(repr, map(float, v64))
['5.0', '0.1', '2.4', '4.555555555555555', '12345678.923456786']

令人惊讶的是,结果看起来很自然并且数字是正确的。有关 2.7/3.2 repr 的更多信息,请参阅 Mark Dickinson 的 What's Newa fascinating lecture

不幸的是,这个技巧不适用于 32 位 float ,至少在没有重新实现 Python 2.7 的 repr 使用的算法的情况下是这样。

关于Python/numpy 浮点文本精度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12502122/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com