uniform(0, 1)
생산할 수는 0
있지만 결코 생산 하지는 않습니다1
.
문서는 엔드 포인트가 있음을 알려줍니다 b
수 생성 된 값에 포함 :
종점 값 b
은 방정식의 부동 소수점 반올림에 따라 범위에 포함되거나 포함되지 않을 수 있습니다 a + (b-a) * random()
.
따라서로 단순화 uniform(0, 1)
된 공식 은 정확하게 생산할 수 있어야 합니다. 1.0 random () 1.0` 인 경우에만 발생합니다 .0 + (1-0) * random()
1 * random()
1
random.random()
exactly. However,
*never* produces
random.random()
문서 인용 :
[0.0, 1.0) 범위에서 다음 임의의 부동 소수점 숫자를 반환합니다.
표기법 [..., ...)
은 첫 번째 값이 가능한 모든 값의 일부이지만 두 번째 값은 그렇지 않음을 의미합니다. random.random()
대부분의 농산물 값에 의지 가까이 에 1.0
. 파이썬의 float
유형은 IEEE 754 base64 부동 소수점 값으로 , 값 을 구성하는 많은 이진 분수 (1/2, 1/4, 1/5 등) 를 인코딩하며 random.random()
생성 되는 값 은 단순히 2 ** -1
(1/2)에서 2 ** -53
(1/9007199254740992) 까지 이러한 53 개의 분획의 무작위 선택 .
그러나 1.0
부동 소수점 숫자를 곱할 때 발생하는 반올림 오류와 함께 매우 가까운 값을 생성 할 수 있으므로 및의 일부 값에 b
대해 생성 할 수 있습니다 . 그러나 및 해당 값 사이에 없습니다.a
b
0
1
주 random.random()
수 0.0을 생성하므로 a
항상 사용할 수있는 값에 포함되어있다 random.uniform()
( a + (b - a) * 0 == a
). 생산할 수 있는 2 ** 53
다른 값 random.random()
(53 개의 이진 분수의 모든 가능한 조합)이 2 ** 53
있기 때문에 그 일이 발생할 확률은 1 in (9007199254740992의 1)입니다.
따라서 random.random()
생산할 수 있는 가장 높은 값 은 1 - (2 ** -53)
; b - a
더 높은 random.random()
값을 곱할 때 반올림이 시작되도록 충분히 작은 값을 선택하십시오 . 작을 b - a
수록 그 가능성이 커집니다.
>>> 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
를 누르면 b = 0.0
1023 번을 나눈 값이며, 위의 값은 1019 나누기 후에 운이 좋았다는 의미입니다. 지금까지 찾은 가장 높은 값 (위의 루프에서 위의 함수를 실행 max()
)은 8.095e-320
(1008 나누기)이지만 더 높은 값이있을 수 있습니다. 그것은 모두 우연의 게임입니다. :-)
또한 사이하지 많은 이산 단계가있는 경우 발생할 수 a
와 b
때 같은 a
과 b
높은 지수를 가지고 지금까지 아파트로 나타날 수 있습니다. 부동 소수점 값은 여전히 근사치이며 인코딩 할 수있는 값의 수는 한정되어 있습니다. 예를 들어, sys.float_info.max
과 의 차이는 1 진 sys.float_info.max - (2 ** 970)
소수만이므로 50-50 확률 random.uniform(sys.float_info.max - (2 ** 970), sys.float_info.max)
은 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)
, 다음이P(X=x)
있다 거의 확실하게 0 X의 모든 값에 대해. (간격에 가능한 많은 값이 있기 때문입니다.) 정확히 0 또는 1을 찾으려면 다른 기능을 사용해야합니다 (예random.choice