python - 타입 - 파이썬 최대 최소




1에서 sys.maxsize 범위의 임의의 숫자는 항상 1 mod 2 ^ 10입니다. (2)

파이썬 (2.7.10)에서 사용할 수있는 PRNG의 통계적 속성을 주파수 테스트, 실행 테스트 및 카이 제곱 테스트를 통해 찾으려고합니다.

빈도 테스트를 수행하기 위해 생성 된 난수를 이진 표현으로 변환 한 다음 10 의 분포를 계산해야합니다. 나는 파이썬 콘솔에서 난수의 이진 표현을 실험하고 있었고 이상한 행동을 관찰했다.

>>> for n in random.sample(xrange(1, sys.maxsize), 50):
...     print '{0:b}'.format(n)
... 
101101110011011001110011110110101101101101111111101000000000001
110000101001001011101001110111111110011000101011100010000000001
110111101101110011100010001010000101011111110010001110000000001
100001111010011000101001000001000011001111100000001010000000001
1111000010010011111100111110110100100011110111010000000000001
111000001011101011101110100001001001000011011001110110000000001
1000100111011000111000101010000101010100110111000100000000001
11101001000001101111110101111011001000100011011011010000000001
110011010111101101011000110011011001110001111000001010000000001
110110110110111100011111110111011111101000011001100000000001
100010010000011101011100110101011110111100001100100000000000001
10111100011010011010001000101011001110010010000010010000000001
101011100110110001010110000101100000111111011101011000000000001
1111110010110010000111111000010001101011011010101110000000001
11100010101101110110101000101101011011111101101000010000000001
10011110110110010110011010000110010010111001111001010000000001
110110011100111010100111100100000100011101100001100000000000001
100110011001101011110011010101111101100010000111001010000000001
111000101101100111110010110110100110111001000101000000000000001
111111101000010111001011111100111100011101001011010000000001
11110001111100000111010010011111010101101110111001010000000001
100001100101101100010101111100111101111001101010101010000000001
11101010110011000001101110000000001111010001110111000000000001
100111000110111010001110110101001011100101111101010000000001
100001101100000011101101010101111111011010111110111110000000001
100010010011110110111111111000010001101100111001001100000000001
110011111110010011000110101010101001001010000100011010000000001
1111011010100001001101101000011100001011001110010100000000001
110110011101100101001100111010101111001011111101100000000000001
1010001110100101001001011111000111011100001100000110000000001
1000101110010011011000001011010110001000110100100100000000001
11111110011001011100111110110111000001000100100010000000000001
101111101010000101010111111111000001100101111001011110000000001
10010010111111111100000001010010101100111001100000000000001
111110000001110010001110111101110101010110001110000000000000001
100000101101000110101010010000101101000011111010001110000000001
101001011101100011001000011010010000000111110111100010000000001
10110101010000111010110111001111011000001111001100110000000001
10110111100100100011100101001100000000101110100100010000000001
10010111110001011101001110000111011010110100110111110000000001
111011110010110111011011101011001100001000111001010100000000001
101001010001010100010010010001100111101110101111000110000000001
101011111010000101010101000110001101001001011110000000000001
1010001010111101101010111110110110000001111101101110000000001
10111111111010001000110000101101010101011010101100000000001
101011101010110000001111010100100110000011111100100100000000001
111100001101111010100111010001010010000010110110010110000000001
100111111000100110100001110101000010111111010010010000000000001
100111100001011100011000000000101100111111000111100110000000001
110110100000110111011101110101101000101110111111010110000000001
>>> 

보시다시피, 모든 숫자는 0000000001 끝납니다. 즉, 모든 숫자는 1 mod 2^10 입니다. 이게 왜 그렇게?

또한이 동작은 범위가 1 to sys.maxsize 때 관찰됩니다. 범위가 1 to 2^40 되면이 현상은 관찰되지 않습니다. 이 동작의 이유와 내 코드에 문제가 있는지 여부를 알고 싶습니다.

사용중인 PRNG를 구현하는 임의 라이브러리에 대한 설명서가 here .

더 자세한 정보를 제공해야하는지 알려주세요.


@roeland는 원인을 암시합니다. Python 2에서 sample()int(random.random() * n) 반복적으로 사용합니다. 자세한 것은 소스 코드 (파이썬의 Lib/random.py )를 보라. 즉, random.random() 은 53 개의 의미있는 (0이 아닌) 선행 비트를 반환합니다. int() 는 나머지 하위 비트를 0으로 채 웁니다. (분명히 sys.maxsize == 2**63 - 1 ); 하위 0 비트가 "많이"있는 짝수 정수로 기본 ( xrange(1, sys.maxsize) )을 인덱싱하면 항상 하위 0 비트와 동일한 수의 홀수 정수가 반환됩니다 (마지막 ).

파이썬 3에서는 아무 것도 일어나지 않습니다. 파이썬 3에서는 random 이 더 강력한 알고리즘을 사용하고, 필요하다면 random.random() 돌아갑니다. 예를 들어, 아래의 Python 3.4.3 :

>>> hex(random.randrange(10**70))
'0x91fc11ed768be3a454bd66f593c218d8bbfa3b99f6285291e1d9f964a9'
>>> hex(random.randrange(10**70))
'0x7b07ff02b6676801e33094fca2fcca7f6e235481c479c521643b1acaf4'

편집하다

다음은 64 비트 박스에서 3.4.3 이하의보다 직접적인 관련 예제입니다.

>>> import random, sys
>>> sys.maxsize == 2**63 - 1
True
>>> for i in random.sample(range(1, sys.maxsize), 6):
...    print(bin(i))
0b10001100101001001111110110011111000100110100111001100000010110
0b100111100110110100111101001100001100110001110010000101101000101
0b1100000001110000110100111101101010110001100110101111011100111
0b111110100001111100101001001001101101100100011001001010100001110
0b1100110100000011100010000011010010100100110111001111100110100
0b10011010000110101010101110001000101110111100100001111101110111

파이썬 3은이 경우 전혀 random.random() 을 호출하지 않고 대신에 기본 Mersenne Twister에서 32 비트 청크를 반복적으로 가져옵니다 (32 비트 부호없는 int는이 MT 구현의 "자연스러운"출력 임). 붙여 넣기 적절한 인덱스를 만들기 위해 이들을 함께 사용합니다. 그래서, Python 3에서, 플랫폼 부동 소수점은 그것과 아무 상관이 없습니다. 파이썬 2에서, float 행동의 단점은 그것과 관련이 있습니다.


이는 RNG가 얼마나 정확하게 구현되었는지, 사용되는 비트의 양, sample 함수가 얼마나 정확하게 구현되었는지 등과 같은 많은 것들에 달려 있습니다.

설명서의 내용은 다음과 같습니다.

거의 모든 모듈 함수는 반 개방 범위 [0.0, 1.0]에서 균일하게 무작위 부동 소수점을 생성하는 기본 함수 random ()에 의존합니다. 파이썬은 Mersenne Twister를 코어 생성기로 사용합니다. 53 비트 정밀도 부동 소수점을 생성하며 기간은 2 ** 19937-1입니다.

따라서 sample 실제로 후드에서 random() 사용하면 결과에 의미있는 비트가 53 비트 만 있어야합니다.







random