python - random.uniform(0,1) 可以生成 0 或 1 吗?

标签 python random uniform-distribution

the documentation据说 uniform(0,1) 有可能生成值 01

我已经运行了 uniform(0, 1) 10000 次,但从未产生过零。即使在 uniform(0, 0.001) 的情况下也是如此。

random.uniform(0,1) 可以生成 01 吗?

最佳答案

uniform(0, 1)可生产0 ,但它永远不会产生 1 .

documentation告诉您端点 b 可以包含在生成的值中:

The end-point value b may or may not be included in the range depending on floating-point rounding in the equation a + (b-a) * random().

所以对于uniform(0, 1) ,公式0 + (1-0) * random() ,简化为1 * random() ,必须能够生成1确切地。只有 random.random() 才会发生这种情况是 1.0确切地。然而,random() 从不产生1.0 .

引用 random.random() documentation :

Return the next random floating point number in the range [0.0, 1.0).

符号[..., ...)意味着第一个值是所有可能值的一部分,但第二个值不是。 random.random()最多会产生非常接近 1.0 的值。 Python 的 float类型是 IEEE 754 base64 floating point value ,它对组成该值的多个二进制分数(1/2、1/4、1/5 等)进行编码,并且值 random.random()产生的结果只是从 2 ** -1 中随机选择 53 个这样的分数的总和。 (1/2) 至2 ** -53 (1/9007199254740992)。

但是,因为它可以产生非常接近 1.0 的值,再加上乘以 float 字时出现的舍入误差,您可以生成 b对于 a一些值和b 。但是01不属于这些值。

请注意random.random() 可以产生 0.0,所以 a始终包含在 random.uniform() 的可能值中(a + (b - a) * 0 == a)。因为有2 ** 53 random.random() 的不同值可以产生(这53个二进制分数的所有可能组合),2 ** 53中只有一个1 (所以 9007199254740992 中的 1)发生这种情况的可能性。

所以可能的最高值 random.random()可以生产的是1 - (2 ** -53) ;只需为 b - a 选择一个足够小的值即可允许在乘以更高的值时进行舍入 random.random()值(value)观。较小的b - a也就是说,发生这种情况的可能性越大:

>>> import random, sys
>>> def find_b():
...     a, b = 0, sys.float_info.epsilon
...     while random.uniform(a, b) != b:
...         b /= 2
...     else:
...         return b
...
>>> print("uniform(0, {0}) == {0}".format(find_b()))
...
uniform(0, 4e-323) == 4e-323

如果您点击b = 0.0 ,那么我们已经划分了1023次,上面的值意味着我们在划分了1019次之后幸运了。到目前为止我发现的最高值(使用 max() 在循环中运行上述函数)是 8.095e-320 (1008 个分区),但可能还有更高的值。这都是一场机会游戏。 :-)

如果 a 之间没有太多离散步骤,也可能会发生这种情况。和b ,就像 a 时一样和b具有很高的指数,因此可能看起来相距甚远。浮点值仍然只是近似值,并且它们可以编码的值的数量是有限的。例如,sys.float_info.max 之间只有 1 个二进制小数的差异。和sys.float_info.max - (2 ** 970) ,所以有 50-50 的机会 random.uniform(sys.float_info.max - (2 ** 970), sys.float_info.max)产生sys.float_info.max :

>>> a, b = sys.float_info.max - (2 ** 970), sys.float_info.max
>>> values = [random.uniform(a, b) for _ in range(10000)]
>>> values.count(sys.float_info.max)  # should be roughly 5000
4997

关于python - random.uniform(0,1) 可以生成 0 或 1 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58241868/

相关文章:

python - python 的 ss.kstest 与 R 的 ks.test 的结果冲突(测试样本是否均匀分布)

c++ - 如何使用 std::uniform_int_distribution<T>::param()?

Runif 未生成均匀分布

python - 脚本在执行过程中的某个时刻抛出一些错误

python - 检查并索引 numpy 数组中的非唯一/重复值

python - 使用 CUDA 或 OpenCL 在 python 中进行多维 FFT

string - 在字符串上随机化大小写的最快方法

python - 什么是最好的 Google App Engine blobstore 工作流程?

c - 将 rand() 用于加密不安全的随机数是否可以接受?

python - 优化类模拟代码?