在python中,是否可以在完全开放的时间间隔内生成一个随机数,或者在高端生成一个闭合的随机数?

2024-04-26 01:27:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我想生成一个随机数n,这样n(a,b)或{}的范围内,其中a < b。在python中这是可能的吗?似乎唯一的选择是a + random.random()*(b-a),它包括[a,b)或者{},它包括范围{},所以都不能满足我的需要。在


Tags: random
3条回答

random.randint(a,b)似乎就是这样。https://docs.python.org/2/library/random.html

计算机生成“随机”数字是很棘手的,尤其是“随机”浮点数。你需要仔细考虑你真正想要什么。最后,您将需要在整数上构建一些东西,而不是直接从float中构建。在

实际上,在Python(以及其他所有使用Mersenne Twister源代码的语言)中,生成一个“随机”的IEEE-754 double(Python的基本random.random())实际上是通过生成一个随机的53位整数,然后除以2**53来实现的:

randrange(2**53) / 9007199254740992.0

这就是为什么输出范围是[0.0, 1.0),但并非该范围内所有可表示的浮点都是相同的。只有那些可以用I/2**53形式表示的整数0 <= I < 2**53。例如,float 1.0 / 2**60永远不能返回。在

这里没有“实数”,只有可表示的二进制浮点数,所以要回答您的问题,首先需要您指定要从中选取的精确的一组。在

如果答案是你不想变得那么挑剔,那么开放和封闭的区别也太挑剔了。如果可以指定精确集,那么解决方案是生成映射到输出集的或多或少明显的随机整数。在

例如,如果你想从基数点后2位的[3.0,6.0]中选取“随机”浮点,有13个可能的输出。所以第一步是

^{pr2}$

然后映射到感兴趣的范围:

return 3.0 + i / 4.0

编辑:没用,但很有教育意义;-)

如注释中所述,可以从所有可表示的浮动中均匀地选取x,并带有{},但要在整个范围内均匀分布还远远不够。例如,在[0.5, 1.0)中有2**52可表示的浮动,2**52在{}中也有{}可表示的浮动,以及。。。在[2.0**-i, 2.0**(1-i))中增加{},直到当我们到达低于正常范围时,可表示的浮点数开始减少,当我们完全下溢到0时,最终下降到零。在

但是,作为位模式,它们非常简单:(0, 1)中可表示的IEEE-754双精度(几乎所有平台上的Python浮点数)集包括,当将位模式视为整数时,简单地

range(1, 0x3ff0000000000000)

因此,一个生成每个具有相同可能性的函数很容易使用位技巧编写:

from struct import unpack
from random import randrange

def gen01():
    i = randrange(1, 0x3ff0000000000000)
    as_bytes = i.to_bytes(8, "big")
    return unpack(">d", as_bytes)[0]

只需运行几次,看看为什么它是无用的-它非常严重地偏向0.0的范围的末端:

>>> for i in range(10):
...     print(gen01())

9.796357610869274e-104
4.125848254595866e-197
1.8114434720880952e-253
1.4937625148849258e-285
1.0537573744489343e-304
2.79008159472542e-58
4.718459887295062e-217
2.7996009087703915e-295
3.4129442284798105e-170
2.299402306630583e-115

对于(a, b],请执行b - random.random()*(b-a)。在

相关问题 更多 >