web-dev-qa-db-fra.com

Traitement de très grands nombres dans Python

J'ai envisagé l'évaluation rapide des mains de poker en Python. Je pensais qu'une des façons d'accélérer le processus serait de représenter tous les visages et les couleurs de la carte sous forme de nombres premiers et de les multiplier ensemble pour représenter les mains. À blanc:

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]

ET

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

Cela donnerait à chaque main une valeur numérique qui, par modulo, pourrait me dire combien de rois sont dans la main ou combien de cœurs. Par exemple, toute main comportant au moins cinq clubs se divise également par 2 ^ 5; toute main avec quatre rois se diviserait également par 59 ^ 4, etc.

Le problème est qu’une main à sept cartes comme AcAdAhAsKdKhKs a une valeur de hachage d’environ 62,7 quadrillions, ce qui prendrait considérablement plus de 32 bits à représenter en interne. Existe-t-il un moyen de stocker des nombres aussi importants dans Python qui me permettra d’effectuer des opérations arithmétiques sur celui-ci?

113
Yes - that Jake.

Python supporte un type entier "bignum" qui peut fonctionner avec des nombres arbitrairement grands. Dans Python 2.5+, ce type s'appelle long et est distinct du type int, mais l'interpréteur utilisera automatiquement celui qui convient le mieux. In = Python 3.0+, le type int a été complètement supprimé.

Cependant, il ne s'agit que d'un détail d'implémentation: si vous possédez la version 2.5 ou supérieure, effectuez simplement des opérations mathématiques standard et tout nombre dépassant les limites des calculs 32 bits sera automatiquement (et de manière transparente) converti en bignum.

Vous pouvez trouver tous les détails sanglants dans PEP 0237 .

152
Ben Blank

support de python arbitrairement large entiers naturellement:

exemple:

>>> 10 ** 1000 100000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000 000000000000000000000000000000000000000000000000

Vous pouvez même obtenir, par exemple, une valeur entière énorme, fib (4000000).

Mais toujours il pas (pour l'instant) supporte un float arbitrairement grand !!

Si vous avez besoin d'un grand, grand, flottez puis vérifiez sur le module décimal. Il existe des exemples d'utilisation sur ces foruns: OverflowError: (34, 'Résultat trop important'))

Une autre référence: http://docs.python.org/2/library/decimal.html

Vous pouvez même utiliser le module gmpy si vous avez besoin d’une accélération (qui risque de vous intéresser): Gestion des grands nombres dans le code

Autre référence: https://code.google.com/p/gmpy/

52
Nuno Aniceto

Vous pouvez le faire pour le plaisir, mais à part ça, ce n'est pas une bonne idée. Cela n'accélérerait pas tout ce à quoi je peux penser.

  • Obtenir les cartes dans une main sera une opération de factorisation d’entiers, ce qui coûtera beaucoup plus cher que de simplement accéder à un tableau.

  • L'ajout de cartes équivaudrait à la multiplication et à la suppression de la division des cartes, deux grands nombres comportant plusieurs mots, qui sont des opérations plus coûteuses que l'ajout ou la suppression d'éléments dans des listes.

  • La valeur numérique réelle d'une main ne vous dira rien. Vous devrez factoriser les nombres premiers et suivre les règles du poker pour comparer deux mains. h1 <h2 pour de telles mains ne signifie rien.

29
Tom

python supporte naturellement des entiers arbitrairement grands:

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