在研究this question并阅读random.py
中的源代码时,我开始怀疑randrange
和{randrange
基本上被实现为
start + int(random.random()*(stop-start))
(假设start
和stop
的整数值),因此randrange(1, 10)
应该返回一个介于1和9之间的随机数。在
randint(start, stop)
正在调用randrange(start, stop+1)
,因此返回一个介于1和10之间的数字。在
我现在的问题是:
如果random()
返回1.0
,那么{
来自Python文档:
就像几乎所有的浮点数。。在
其他答案指出,
random()
的结果总是严格地小于1.0
;然而,这只是故事的一半。在如果您将},以及任何正整数}是正确的,因此{}严格小于{}。在
randrange(n)
计算为int(random() * n)
,那么您还需要知道,对于满足0.0 <= x < 1.0
的任何Python浮点{n
,那么{有两件事可能会出错:首先,当我们计算
x * n
,n
被隐式转换为浮点。对于足够大的n
,该转换可能会更改该值。但是如果你看一下Python源代码,你会发现它只对小于n
的int(random() * n)
方法使用(在这里和下面,我假设平台使用ieee754双精度),这是保证n
到float的转换不会丢失信息的范围(因为n
可以精确地表示为float)。在第二个可能出错的地方是乘法
x * n
(现在作为float的乘积执行)的结果可能不完全可表示,因此会涉及一些舍入。如果x
与1.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的可能性,这使得}。有关详细信息,请参阅http://bugs.python.org/issue24546上的讨论。在
random() * n
在random()
返回最大可能值的情况下,将up取整为n
。可能发生这种情况的最小的n
是{来自
random.py
和文档:)
表示间隔是独占的1.0。也就是说,它永远不会返回1.0。在这是数学中的一个普遍惯例,}是包含的,而{}和{}是互斥的,这两种类型的括号可以混合为}。请查看wikipedia: Interval (mathematics)以获得正式解释。在
[
和{(a, b]
或{相关问题 更多 >
编程相关推荐