Можно ли найти случайные числа с плавающей точкой в ​​диапазоне [a, b] в Python? - PullRequest
3 голосов
/ 09 марта 2011

Я пытаюсь генерировать в python случайные числа с плавающей точкой в ​​диапазоне [0,8,0,9], но, к сожалению, все найденные мной инструменты могут генерировать случайные числа в диапазоне [a, b) для чисел с плавающей точкой. (вроде Random.uniform(a,b))

Тем временем я пытался сделать что-то вроде этого:

uniform(0.8,0.90000000001)

но это очень плохо

есть идеи?

Ответы [ 5 ]

7 голосов
/ 09 марта 2011

Разница между [0,8, 0,9] и [0,8,0,9) исчезающе мала. Учитывая ограничения двоичной плавающей запятой, я не думаю, что есть даже разница, так как 0.9 не может быть точно представлено в любом случае. Используйте [0.8,0.9).

3 голосов
/ 09 марта 2011

Цитирование строки документа random.uniform():

Получить случайное число в диапазоне [a, b) или [a, b] в зависимости от округления.

Таким образом, вы даже не знаете, включена ли конечная точка или нет.Но вас это тоже не должно волновать - в диапазоне [0,8, 0,9] есть 900719925474100 чисел с плавающей запятой.В любом случае, потребуется время до тех пор, пока не произойдет хотя бы одно из них, поэтому нет никакой практической разницы, включать ли конечную точку или нет, даже если конечная точка может быть представлена ​​точно как число с плавающей запятой.

2 голосов
/ 09 марта 2011

Вероятность создания значения конечной точки должна быть незначительной.О каких плохих последствиях вы беспокоитесь, если просто используете Random.uniform(0.8,0.9)?(И вас также беспокоит тот факт, что поплавки двойной точности, которые вы получаете, когда говорите «0.8» и «0.9», на самом деле не совсем 8/10 и 9/10?)1005 * Возможно, у вас очень необычные требования;но, скажем, для 99,9% приложений, я думаю, ответ: просто используйте Random.uniform(a,b) и не беспокойтесь об этом.

1 голос
/ 10 марта 2011

Если это действительно имеет значение, то вы можете сделать это:

def uniform_closed(a, b):
     while True:
         r = random.uniform(a, b + (b - a) * 0.01)
         if r <= b: return r
1 голос
/ 09 марта 2011

В документах говорится, что uniform(a, b) генерирует число в [a, b] 1 , но это похоже на ошибку документации, поскольку source показывает, что он полагается на random(), который, согласно документам, возвращает [0.0, 1.0) 2 .

Если у вас должен быть [a, b], то вы можетепопробуйте сгенерировать этот диапазон из целого числа:

random.inclusive_uniform = lambda a, b:
    random.randint(0, 0xFFFFFFFF) / float(0xFFFFFFFF) * (b - a) + a

Я говорю «попробуйте» сгенерировать этот диапазон, потому что когда границы не могут быть точно представлены (ни 0,8, ни 0,9 не могут быть точно представлены в IEEE-754), тогдадиапазон на самом деле [a ', b'], где a 'и b' - все, к чему округляются a и b.Обратите внимание, что это может быть даже больше, чем диапазон [a, b], поэтому будьте осторожны!

1 В частности, он говорит, что возвращаемое значение N ограничено a <= N <= b.

2 В комментарии в источнике, однако, есть утверждение, что оно никогда не может быть 0,0, поэтому я предполагаю, что диапазон на самом деле (0,0,1,0).

...