uniform(0, 1)
üretebilir 0
, ama asla üretmez 1
.
Dokümantasyon son nokta olduğunu söyler b
olabilir üretilen değerler dahil edilmesi:
Uç nokta değeri b
, denklemdeki kayan nokta yuvarlamasına bağlı olarak aralığa dahil edilebilir veya edilmeyebilir a + (b-a) * random()
.
Dolayısıyla , sadeleştirilmiş uniform(0, 1)
formülün tam olarak üretebilmesi gerekirdi . Bu sadece 1.0 rasgele () 1.0` olduğunda olur.0 + (1-0) * random()
1 * random()
1
random.random()
exactly. However,
*never* produces
random.random()
Belgelerin alıntılanması :
[0.0, 1.0) aralığındaki bir sonraki rasgele kayan nokta sayısını döndürün.
Gösterim [..., ...)
, ilk değerin tüm olası değerlerin bir parçası olduğu, ancak ikincisinin olmadığı anlamına gelir. random.random()
En üretim değerlerinde irade çok yakındır için 1.0
. Python'un float
türü, değeri oluşturan bir dizi ikili fraksiyonu (1/2, 1/4, 1/5, vb.) Kodlayan bir IEEE 754 base64 kayan nokta değeridir ve üretilen değer random.random()
basitçe bir 2 ** -1
(1/2) 'den 2 ** -53
(1/9007199254740992)' ye kadar olan bu 53 fraksiyonun rasgele seçimi .
Çok yakın değerler üretebilir Ancak, 1.0
birlikte size çarpma noktası nubmers kayan ortaya çıkan hataları yuvarlama ile, sen yapabilirsiniz üretmek b
için bazı değerleri a
ve b
. Ancak 0
ve 1
bu değerler arasında değildir.
Not random.random()
olabilir 0.0 üretmek, yani a
, her zaman için olası değerleri dahildir random.uniform()
( a + (b - a) * 0 == a
). Üretebilecek 2 ** 53
farklı değerler olduğundan random.random()
(bu 53 ikili fraksiyonun tüm olası kombinasyonları), bunun gerçekleşmesi için sadece 1 inç 2 ** 53
(yani 9007199254740992'de 1) şansı vardır.
Böylece random.random()
üretebilecek en yüksek değer 1 - (2 ** -53)
; b - a
daha yüksek random.random()
değerlerle çarpıldığında yuvarlamanın devreye girmesine izin verecek kadar küçük bir değer seçmeniz yeterlidir . Ne kadar küçükse b - a
, bunun gerçekleşme şansı o kadar artar:
>>> import random, sys
>>> def find_b():
... a, b = 0, sys.float_info.epsilon
... while random.uniform(a, b) != b:
... b /= 2
... else:
... return b
...
>>> print("uniform(0, {0}) == {0}".format(find_b()))
...
uniform(0, 4e-323) == 4e-323
Eğer vurursanız b = 0.0
, 1023 kez böldük, yukarıdaki değer 1019 bölümden sonra şanslı olduğumuz anlamına gelir. Şimdiye kadar bulduğum en yüksek değer (yukarıdaki işlevi bir döngüde çalıştırmak max()
) 8.095e-320
(1008 bölüm), ancak muhtemelen daha yüksek değerler var. Hepsi bir şans oyunu. :-)
Ayrıca aralarında birçok ayrık adımlar olup olmadığını ortaya çıkabilir a
ve b
zaman gibi a
ve b
yüksek üs var ve şu ana kadar appart gibi görünebilir. Kayan nokta değerleri hala sadece yaklaşık değerlerdir ve kodlayabilecekleri değerlerin sayısı sonludur. Örneğin, orada arasındaki farkın sadece 1 ikili kesir olan sys.float_info.max
ve sys.float_info.max - (2 ** 970)
50-50 şansı bir yoktur, böylece random.uniform(sys.float_info.max - (2 ** 970), sys.float_info.max)
üretir sys.float_info.max
:
>>> a, b = sys.float_info.max - (2 ** 970), sys.float_info.max
>>> values = [random.uniform(a, b) for _ in range(10000)]
>>> values.count(sys.float_info.max) # should be roughly 5000
4997
X ~ U(0,1)
, o zamanP(X=x)
olduğu hemen hemen kesin 0 x tüm değerleri için. (Bunun nedeni aralıkta sonsuz sayıda olası değer bulunmasıdır.) Tam olarak 0 veya 1 arıyorsanız, farklı bir işlev kullanmalısınızrandom.choice