在 the documentation据说 uniform(0,1)
有可能生成值 0
和 1
。
我已经运行了 uniform(0, 1)
10000 次,但从未产生过零。即使在 uniform(0, 0.001)
的情况下也是如此。
random.uniform(0,1)
可以生成 0
或 1
吗?
最佳答案
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 equationa + (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
。但是0
和1
不属于这些值。
请注意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/