我想制作一个 numpy.float128s 类型的随机数组。这是无效的:
import numpy as np
a = np.random.random(100, dtype=np.float128) # not valid code
我可以做
a = np.random.random(100).astype(np.float128)
但这会创建 64 位浮点数,然后将它们转换为 np.float128 (实际上是 80 位,但这不是这里的问题)。所以这个精度是错误的。
有什么方法可以创建 0 到 1 范围内的随机 np.float128s 数组吗?
64 位浮点数有 53 个小数位,即它可以包含
2**53
种不同的状态,而 128 位浮点数有 2**113
种状态。 Numpy 还没有 128 位整数类型。
有几种方法可以将它们组合起来生成单个 128 位浮点数,但如果必须的话,我想我可能会使用一对无符号 64 位整数。下面是一些代码,其执行方式与在其他地方创建随机 64 位浮点的方式类似。
import numpy as np
# divides are relatively slow, do this once
RNORM = 1. / np.float128([2**64+1, 2**128])
# put a single 128bit float in rv
state = np.random.randint(2**64, size=2, dtype=np.uint64)
rv = np.sum(state.astype(np.float128) * RNORM)
也就是说,即使简单的方式(即生成 float64 并转换为 float128)“仅”给你 53 位状态,这仍然是很多,几乎 1e16 个状态。我有兴趣知道为什么你认为你需要更多——尤其是在 Python 中!
随机浮点数生成很棘手,尤其是“均匀”分布。您希望 P(x) 大约等于
np.spacing(x)
,即 P(0.25) = P(0.5) /2 (!)
现在,
np.float128
(真的是np.longdouble
)的间距比np.float64
小2048倍。因此,您使用简单的方法会错过大约 99.95% 的可能输出。
不过,这很容易解决。给定一个随机
x : np.float64
,添加 np.spacing(x) * np.random.randint(low=0, high=2048)
可以正确设置缺失的 11 位。