可能随机.randint(1,10)是否返回11?

2024-06-07 04:19:16 发布

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

在研究this question并阅读random.py中的源代码时,我开始怀疑randrange和{}是否真的像“广告”一样。我非常倾向于相信这一点,但是我阅读它的方式,randrange基本上被实现为

start + int(random.random()*(stop-start))

(假设startstop的整数值),因此randrange(1, 10)应该返回一个介于1和9之间的随机数。在

randint(start, stop)正在调用randrange(start, stop+1),因此返回一个介于1和10之间的数字。在

我现在的问题是:

如果random()返回1.0,那么{}会返回{},不是吗?在


Tags: py源代码方式数字整数randomthisstart
3条回答

来自Python文档:

Almost all module functions depend on the basic function random(), which generates a random float uniformly in the semi-open range [0.0, 1.0).

就像几乎所有的浮点数。。在

其他答案指出,random()的结果总是严格地小于1.0;然而,这只是故事的一半。在

如果您将randrange(n)计算为int(random() * n),那么您还需要知道,对于满足0.0 <= x < 1.0的任何Python浮点{},以及任何正整数n,那么{}是正确的,因此{}严格小于{}。在

有两件事可能会出错:首先,当我们计算x * nn被隐式转换为浮点。对于足够大的n,该转换可能会更改该值。但是如果你看一下Python源代码,你会发现它只对小于nint(random() * n)方法使用(在这里和下面,我假设平台使用ieee754双精度),这是保证n到float的转换不会丢失信息的范围(因为n可以精确地表示为float)。在

第二个可能出错的地方是乘法x * n(现在作为float的乘积执行)的结果可能不完全可表示,因此会涉及一些舍入。如果x1.0足够接近,可以想象舍入将结果舍入到n本身。在

为了确保不会发生这种情况,我们只需要考虑x的最大可能值,即(在几乎所有运行Python的机器上)1 - 2**-53。所以我们需要证明正整数(1 - 2**-53) * n < n,因为random() * n <= (1 - 2**-53) * n永远是真的。在

证明(草图)让k是唯一的整数k,这样2**(k-1) < n <= 2**k。下一个从n向下浮动的是n - 2**(k-53)。我们需要证明n*(1-2**53)(即,未取整的乘积的实际值)更接近n - 2**(k-53),而不是{},这样它总是向下取整。但是一个小算式表明n*(1-2**-53)到{}的距离是2**-53 * n,而{}到{}的距离是{}。但是2**k - n < n(因为我们选择了k,所以2**(k-1) < n),所以乘积更接近n - 2**(k-53),所以它的将被向下取整(假设平台正在进行某种形式的舍入)。在

所以我们安全了。嘘!在


附录(2015-07-04):上述假设采用IEEE 754二进制64算法,并将舍入连接到偶数舍入模式。在许多机器上,这种假设是相当安全的。然而,在使用x87 FPU进行浮点运算的x86机器上(例如,各种风格的32位Linux),在乘法中存在double rounding的可能性,这使得random() * nrandom()返回最大可能值的情况下,将up取整为n。可能发生这种情况的最小的n是{}。有关详细信息,请参阅http://bugs.python.org/issue24546上的讨论。在

来自random.py和文档:

"""Get the next random number in the range [0.0, 1.0)."""

)表示间隔是独占的1.0。也就是说,它永远不会返回1.0。在

这是数学中的一个普遍惯例,[和{}是包含的,而{}和{}是互斥的,这两种类型的括号可以混合为(a, b]或{}。请查看wikipedia: Interval (mathematics)以获得正式解释。在

相关问题 更多 >