파이썬에서 매우 많은 수의 처리


140

파이썬에서 빠른 포커 핸드 평가를 고려하고 있습니다. 프로세스 속도를 높이는 한 가지 방법은 모든 카드 얼굴과 양복을 소수로 표현하고 손을 표현하기 위해 함께 곱하는 것입니다. 오순절 :

class PokerCard:
    faces = '23456789TJQKA'
    suits = 'cdhs'
    facePrimes = [11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 53, 59, 61]
    suitPrimes = [2, 3, 5, 7]

    def HashVal(self):
      return PokerCard.facePrimes[self.cardFace] * PokerCard.suitPrimes[self.cardSuit]

이것은 모듈로를 통해 손에 몇 명의 왕이 있는지 또는 얼마나 많은 마음을 말해 줄 수있는 숫자 값을 각 손에 줄 것입니다. 예를 들어, 클럽이 5 개 이상인 손은 2 ^ 5로 균등하게 나눕니다. 네 왕이있는 손은 59 ^ 4 등으로 균등하게 나눕니다.

문제는 AcAdAhAsKdKhKs와 같은 7 장의 카드 핸드가 약 62.7 조의 해시 값을 가지며 내부적으로 표현하는 데 32 비트 이상이 소요된다는 것입니다. 파이썬에 산술 연산을 수행 할 수있는 많은 수의 파이썬을 저장하는 방법이 있습니까?


13
이런 식으로 데이터 표현을 시작한 후에도 여전히 속도가 크게 향상 될 것입니까? 이것이 귀하의 질문에 대한 답변은 아니지만 여전히 ..
Thomi

3
카드 값과 표현에 별도의 변수를 사용하는 대신 사전을 사용하는 것이 좋습니다. (따라서면 = { '2': 11, '3': 13, '4': 17, '5': 19, '6': 23, '7': 29, '8': 31, '9' : 37, 'T': 41, 'J': 43, 'Q': 53, 'K': 59, 'A': 61} 및 정장 = { 'c': 2, 'd': 3, ' h ': 5,'s ': 7}.)
JAB

답변:


177

파이썬은 "큰 숫자"정수 타입을 지원하는데, 이것은 임의의 큰 숫자와 함께 작동 할 수 있습니다. Python 2.5 이상에서는이 유형이 호출 long되고 유형 과 별개 int이지만 인터프리터는 더 적합한 것을 자동으로 사용합니다. Python 3.0 이상에서는 int유형이 완전히 삭제되었습니다.

2.5 이상 버전을 사용하는 한 표준 수학 연산 만 수행하면 32 비트 수학의 경계를 초과하는 숫자는 자동으로 (투명하게) 큰 숫자로 변환됩니다.

모든 까다로운 세부 사항은 PEP 0237 에서 찾을 수 있습니다 .


2
문제는 32 비트 정수 대신 bignum을 사용했을 때의 성능 저하가 그가 사용하는 영리한 손 평가 방법의 성능 이점을 초과한다는 것입니다.
Chris Upchurch

3
실제로 int와 long 사이의 장벽은 2.5에서 깨졌습니다. 3.0은 int를 모두 제거하여 정수 유형 만 길게 만듭니다.
Ignacio Vazquez-Abrams

1
숫자가 얼마나 큽니까? PHI ^ 4000000 일 수 있습니까?
Mike Caron

9
@Mike Caron — PEP 0237에 나열된 구조체가 정확하면 longs의 길이 (자리)는 부호없는 32 비트 정수 (최대 4,294,967,295 자리)로 저장되므로 쉽게 φ ** (4 * 10 ** 6을 보유 할 수 있음) ), 832,951 자리 만 그러나 φ는 정수가 아니므로 10 진수 (Python의 부동 소수점 큰 숫자)를 사용하여 숫자를 계산해야합니다. long그러나 결과를 나중에 저장할 수 있습니다 .
Ben Blank

17
@ IgnacioVazquez-Abrams 설명의 요점은 long3.0의 유일한 정수 유형이지만 이름은 int입니다. (그리고 오래된 int것이 사라졌습니다.)
Michael Mior

70

파이썬은 자연스럽게 임의의정수를 지원합니다 .

예:

>>>10 ** 1000 100000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000

예를 들어 fib (4000000)과 같은 거대한 정수 값을 얻을 수도 있습니다.

그러나 여전히 그것은 (현재) 임의로 큰 플로트를 지원 하지 않습니다 !

하나의 크고 큰 float이 필요한 경우 십진 모듈을 확인하십시오. 이러한 foruns에 대한 사용 예가 있습니다 : OverflowError : (34, 'Result too large')

또 다른 참조 : http://docs.python.org/2/library/decimal.html

당신은 속도 향상 (당신의 관심이 될 가능성이 높습니다)를해야하는 경우도 gmpy 모듈을 사용 할 수 있습니다 코드에서 큰 숫자 처리

또 다른 참조 : https://code.google.com/p/gmpy/


33

당신은 그것의 재미를 위해 이것을 할 수 있지만, 그 외에는 좋은 생각이 아닙니다. 내가 생각할 수있는 것은 속도가 빨라지지 않습니다.

  • 카드를 손에 넣는 것은 단순히 배열에 액세스하는 것보다 훨씬 비싼 정수 팩터링 작업입니다.

  • 카드를 추가하면 곱셈과 큰 여러 단어로 된 카드 분할이 제거되므로 목록에서 요소를 추가하거나 제거하는 것보다 비용이 많이 듭니다.

  • 손의 실제 숫자 값은 아무 것도 알려주지 않습니다. 소수를 비교하고 포커 규칙을 따라 두 손을 비교해야합니다. 그러한 손에 대한 h1 <h2는 아무것도 의미하지 않습니다.


25

파이썬은 자연스럽게 임의의 큰 정수를 지원합니다.

In [1]: 59**3*61**4*2*3*5*7*3*5*7
Out[1]: 62702371781194950
In [2]: _ % 61**4
Out[2]: 0

3

파이썬 인터프리터가 당신을 위해 그것을 처리 할 것입니다, 당신은 당신의 작업 (+,-, *, /)을 수행해야하며 정상적으로 작동합니다.

int값은 제한이 없습니다.

나눗셈을 할 때주의해야합니다. 기본적으로 몫은로 바뀌지 floatfloat이러한 큰 수는 지원하지 않습니다. float큰 숫자를 지원하지 않는다는 오류 메시지가 표시 되면 몫이 너무 커서 저장 float하기에 바닥 나누기 ( //) 를 사용해야 한다는 의미 입니다.

소수점 다음에 오는 소수점을 무시합니다.이 방법으로 결과는 int이므로 많은 수의 결과를 얻을 수 있습니다.

10//3 출력 3

10//4 출력 2


1
귀하의 답변은 질문에서 많은 수의 문제를 어떻게 해결합니까?
StupidWolf

그것은 당신이 많은 숫자로 정상적인 작업을 수행 할 수 있지만 분할에주의해야 함을 의미합니다
Hedy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.