Обработка очень больших чисел в Python

Я рассматривал быструю оценку рук в Python. Мне пришло в голову, что одним из способов ускорить процесс было бы представлять все грани карт и костюмы в виде простых чисел и умножать их вместе, чтобы представлять руки. Для whit:

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]

Это даст каждой руке числовое значение, которое через modulo могло бы рассказать мне, сколько королей находится в руке или сколько сердец. Например, любая рука с пятью или более клубами в ней будет разделяться равномерно на 2 ^ 5; любая рука с четырьмя царями будет равномерно разделяться на 59 ^ 4 и т.д.

Проблема состоит в том, что карта с семью картами, такая как AcAdAhAsKdKhK, имеет хеш-значение около 62,7 квадриллионов, что будет представлять собой более 32 бит для представления внутри компании. Есть ли способ хранить такие большие числа в Python, которые позволят мне выполнять арифметические операции над ним?

Ответ 1

Python поддерживает целочисленный тип "bignum", который может работать с произвольно большими числами. В Python 2.5+ этот тип называется long и отделен от типа int, но интерпретатор будет автоматически использовать то, что более подходит. В Python 3.0+ тип int полностью отключен.

Это просто деталь реализации, хотя - до тех пор, пока у вас есть версия 2.5 или выше, просто выполняйте стандартные математические операции, и любое число, которое превышает границы 32-битной математики, будет автоматически (и прозрачно) преобразовано в bignum.

Вы можете найти все детали gory в PEP 0237.

Ответ 2

python поддерживает произвольно большие целые числа:

Пример:

→ > 10 ** 1000 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000

Вы даже можете получить, например, огромное целочисленное значение, fib (4000000).

Но все же он не (на данный момент) поддерживает сколь угодно большой float!!

Если вам нужен один большой, большой, плавающий, проверьте на десятичном модуле. Есть примеры использования этих foruns: OverflowError: (34, "Слишком большой результат" )

Другая ссылка: http://docs.python.org/2/library/decimal.html

Вы даже можете использовать модуль gmpy, если вам требуется ускорение (что может вас заинтересовать): Обработка больших чисел в коде

Другая ссылка: https://code.google.com/p/gmpy/

Ответ 3

Вы могли бы сделать это ради удовольствия, но кроме этого это не очень хорошая идея. Это не ускорит все, что я могу придумать.

  • Получение карт в руке будет целочисленной факторинговой операцией, которая намного дороже, чем просто доступ к массиву.

  • Добавление карт было бы умножением и удалением деления карт, причем оба больших числа с несколькими словами, которые являются более дорогостоящими операциями, чем добавление или удаление элементов из списков.

  • Фактическое числовое значение руки ничего не скажет. Вам нужно будет определить простые числа и следовать правилам покера, чтобы сравнить две руки. h1 < h2 для таких рук ничего не значит.

Ответ 4

python поддерживает произвольно большие целые числа:

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