Диапазон Python's random.random () из стандартной библиотеки - PullRequest
16 голосов
/ 02 февраля 2010

Возвращает ли Python random.random () когда-либо 1.0 или только до 0.9999 ..?

Ответы [ 5 ]

33 голосов
/ 02 февраля 2010
>>> help(random.random)
Help on built-in function random:

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

Это означает, что 1 исключено.

21 голосов
/ 02 февраля 2010

Документы здесь: http://docs.python.org/library/random.html

... random (), который генерирует случайное плавание равномерно в полуоткрытый диапазон [0,0, 1,0).

Таким образом, возвращаемое значение будет больше или равно 0 и меньше 1,0.

12 голосов
/ 25 августа 2013

Другие ответы уже разъяснили, что 1 не входит в диапазон, но из любопытства я решил посмотреть на источник, чтобы точно узнать, как он рассчитывается.

Источник CPython можно найти здесь

/* 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

10 голосов
/ 02 февраля 2010

Функция Python random.random возвращает числа, которые меньше, но не равны 1.

Однако он может вернуть 0.

3 голосов
/ 15 апреля 2017

Из кода в ответах Антимонии легко увидеть, что random.random () никогда не возвращает ровно 1.0 на платформах, которые имеют по крайней мере 53-битную мантиссу для вычислений с константами, не помеченными 'f' в C. Это точность IEEE 754 предписывает и сегодня является стандартом.

Однако на платформах с более низкой точностью, например, если Python скомпилирован с -fsingle-precision-constant для использования на встроенной платформе, добавление b к a * 67108864.0 может привести к округлению до 2 ^ 53, если b близко достаточно 2 ^ 26, и это будет означать, что 1,0 возвращается. Обратите внимание, что это происходит независимо от того, какую точность использует Python-функция PyFloat_FromDouble.

Один из способов проверить это - проверить несколько сотен случайных чисел, равен ли когда-либо 53-й бит 1. Если он равен 1, то хотя бы раз это подтверждает достаточную точность, и у вас все хорошо. В противном случае округление является наиболее вероятным объяснением, означающим, что random.random () может вернуть 1.0. Конечно, возможно, что вам просто не повезло. Вы можете повысить достоверность до желаемого уровня, протестировав большее количество чисел.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...