Обработка очень больших чисел в Python - PullRequest
104 голосов
/ 11 февраля 2009

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

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]

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

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

Ответы [ 4 ]

148 голосов
/ 11 февраля 2009

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

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

Все подробности можно найти в PEP 0237 .

50 голосов
/ 07 января 2014

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

пример:

>>> 10 ** 1000 100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000

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

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

Если вам нужен один большой, большой, float, тогда проверьте десятичный модуль. Вот примеры использования этих foruns: OverflowError: (34, 'Результат слишком велик')

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

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

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

28 голосов
/ 12 февраля 2009

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

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

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

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

23 голосов
/ 11 февраля 2009

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

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