【问题标题】:Range of python's random.random() from the standard library标准库中 python 的 random.random() 范围
【发布时间】:2010-02-01 21:45:26
【问题描述】:

python 的 random.random() 会返回 1.0 还是只返回到 0.9999..?

【问题讨论】:

  • 山里有金子。关于 random.random() 返回什么的问题,得到 42 分(并且还在计数)。
  • 请注意,如果您不终止序列 0.9999,它实际上等于 1.0。

标签: python random


【解决方案1】:
>>> help(random.random)
Help on built-in function random:

random(...)
    random() -> x in the interval [0, 1).

这意味着 1 被排除在外。

【讨论】:

  • 我最喜欢你的回答。 Python 有一个很棒的内部帮助系统,应该鼓励人们使用它。
【解决方案2】:

文档在这里:http://docs.python.org/library/random.html

...random(),其中 均匀地生成一个随机浮点数 半开放范围 [0.0, 1.0)。

所以,返回值会大于等于0,小于1.0。

【讨论】:

  • 有关括号/父范围符号的解释,请看这里:en.wikipedia.org/wiki/Interval_(mathematics)#Terminology
  • 我认为当您使用 Python 编程时,Python 的内部帮助系统(如另一个答案中所述)更容易访问。 help(random.random) 会给 OP 他需要的信息。
  • 在网页上写作时最好链接到真实的文档。
【解决方案3】:

其他答案已经说明 1 不包含在范围内,但出于好奇,我决定查看源代码以准确了解它是如何计算的。

CPython源码可以在here找到

/* random_random is the function named genrand_res53 in the original code;
 * generates a random number on [0,1) with 53-bit resolution; note that
 * 9007199254740992 == 2**53; I assume they're spelling "/2**53" as
 * multiply-by-reciprocal in the (likely vain) hope that the compiler will
 * optimize the division away at compile-time.  67108864 is 2**26.  In
 * effect, a contains 27 random bits shifted left 26, and b fills in the
 * lower 26 bits of the 53-bit numerator.
 * The orginal code credited Isaku Wada for this algorithm, 2002/01/09.
 */
static PyObject *
random_random(RandomObject *self)
{
    unsigned long a=genrand_int32(self)>>5, b=genrand_int32(self)>>6;
    return PyFloat_FromDouble((a*67108864.0+b)*(1.0/9007199254740992.0));
}

因此该函数有效地生成m/2^53,其中0 <= m < 2^53 是一个整数。由于浮点数通常具有 53 位精度,这意味着在 [1/2, 1) 范围内,会生成每个可能的浮点数。对于接近 0 的值,它会跳过一些可能的浮点值以提高效率,但生成的数字在该范围内均匀分布。 random.random 生成的最大可能数正好是

0.99999999999999988897769753748434595763683319091796875

【讨论】:

  • 如果上面的 C 代码是用 -fsingle-precision-constant 编译的,这可能会产生 1.0。详情见我的回答
【解决方案4】:

Python 的 random.random 函数返回小于但不等于 1 的数字。

但是,它可以返回0

【讨论】:

  • random() -> x 在区间 [0, 1) 即包括0。
  • @telliott99:这(几乎)正是我所说的。
  • +1 是唯一不依赖科幻数学符号的答案!
  • @Jørn Schou-Rode,我在小学到高中的某个时候了解了开放和封闭的间隔。我不记得什么时候了。人们,尤其是程序员,应该学会理解他们,如果他们还不了解的话。
  • @Omnifarious:很久以前我忘记了他们,我实际上认为这是他们文档中的错字
【解决方案5】:

从 Antimony 的答案中的代码很容易看出 random.random() 永远不会在具有至少 53 位尾数的平台上准确返回 1.0,以用于涉及 C 中未用“f”注释的常量的计算。这就是 IEEE 的精度754 规定并且是今天的标准。

但是,在精度较低的平台上,例如,如果 Python 使用 -fsingle-precision-constant 编译以在嵌入式平台上使用,如果 b 接近,将 b 添加到 a*67108864.0 可能会导致舍入到 2^53足够 2^26 这意味着返回 1.0。请注意,无论 Python 的 PyFloat_FromDouble 函数使用什么精度,都会发生这种情况。

对此进行测试的一种方法是检查数百个随机数,第 53 位是否曾经为 1。如果它至少为 1 一次,这证明了足够的精度,你就可以了。如果不是,四舍五入是最可能的解释,这意味着 random.random() 可以返回 1.0。当然也有可能只是你运气不好。您可以通过测试更多的数字将确定性提高到任意高。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-23
    • 2021-05-23
    相关资源
    最近更新 更多