Omgaan met zeer grote getallen in Python

Ik heb een snelle evaluatie van pokerhanden overwogen in Python. Het kwam bij me op dat een manier om het proces te versnellen zou zijn om alle kaartvlakken en kleuren als priemgetallen weer te geven en ze met elkaar te vermenigvuldigen om de handen weer te geven. Naar wit:

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]

EN

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

Dit zou elke hand een numerieke waarde geven die me via modulo zou kunnen vertellen hoeveel koningen er in de hand zijn of hoeveel harten. Elke hand met vijf of meer klaveren zou bijvoorbeeld gelijk worden gedeeld door 2^5; elke hand met vier koningen zou gelijk worden gedeeld door 59^4, enz.

Het probleem is dat een hand met zeven kaarten zoals AcAdAhAsKdKhKs een hashwaarde heeft van ongeveer 62,7 quadriljoen, wat aanzienlijk meer dan 32 bits zou kosten om intern te representeren. Is er een manier om zulke grote getallen in Python op te slaan dat ik er rekenkundige bewerkingen op kan uitvoeren?


Antwoord 1, autoriteit 100%

Python ondersteunt een “bignum” integer type dat kan werken met willekeurig grote getallen. In Python 2.5+ wordt dit type longgenoemd en staat het los van het type int, maar de interpreter gebruikt automatisch wat het meest geschikt is. In Python 3.0+ is het type intvolledig verwijderd.

Dat is echter slechts een implementatiedetail – zolang je versie 2.5 of beter hebt, voer je gewoon standaard wiskundige bewerkingen uit en elk getal dat de grenzen van 32-bits wiskunde overschrijdt, wordt automatisch (en transparant) geconverteerd naar een bignum.

Je kunt alle bloederige details vinden in PEP 0237.


Antwoord 2, autoriteit 46%

python ondersteunt natuurlijk willekeuriggrote gehele getallen:

voorbeeld:

>>> 10**1000
10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Je zou zelfs, bijvoorbeeld van een enorm geheel getal, fib(4000000) kunnen krijgen.

Maar toch ondersteunt het niet(voorlopig) een willekeurig grote float!!

Als je een grote, grote float nodig hebt, kijk dan eens naar de decimale module. Er zijn voorbeelden van gebruik op deze foruns: OverflowError: (34, ‘Resultaat te groot’)

Nog een referentie: http://docs.python.org/2/library/decimal .html

Je kunt zelfs de gmpy-module gebruiken als je een versnelling nodig hebt (wat waarschijnlijk interessant voor je is): Omgaan met grote getallen in code

Nog een referentie: https://code.google.com/p/gmpy/


Antwoord 3, autoriteit 19%

Je zou dit voor de lol kunnen doen, maar verder is het geen goed idee. Het zou niets versnellen wat ik kan bedenken.

  • Het verkrijgen van de kaarten in een hand zal een integer factoring operatie zijn die veel duurder is dan alleen toegang krijgen tot een array.

  • Het toevoegen van kaarten zou vermenigvuldiging zijn en het verwijderen van kaartendeling, beide van grote getallen van meerdere woorden, wat duurdere bewerkingen zijn dan het toevoegen of verwijderen van elementen uit lijsten.

  • De werkelijke numerieke waarde van een hand zegt niets. U moet de priemgetallen in rekening brengen en de pokerregels volgen om twee handen te vergelijken. h1 < h2 voor zulke handen betekent niets.


Antwoord 4, autoriteit 15%

python ondersteunt natuurlijk willekeurig grote gehele getallen:

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

Antwoord 5, autoriteit 4%

De Python-tolk zal het voor u behandelen, u hoeft alleen maar uw activiteiten (+, -, *, /) te doen en het zal zo normaal werken.

De intWaarde is onbeperkt.

Voorzichtig bij het doen van divisie, wordt het quotiënt standaard ingeschakeld in float, maar floatondersteunt dergelijke grote nummers niet. Als u een foutmelding krijgt, zegt u floatniet ondersteunt dergelijke grote aantallen, dan betekent dit dat het quotiënt te groot is om te worden opgeslagen in floatU moet Floor Division gebruiken (//).

Het negeert elk decimaal dat na het decimale punt komt, op deze manier, het resultaat is int, zodat u een groot aantal resultaat kunt hebben.

>>>10//3
3
>>>10//4
2

Other episodes