Pregunta Manejando números muy grandes en Python


He estado considerando la evaluación rápida de mano de póker en Python. Se me ocurrió que una forma de acelerar el proceso sería representar todas las caras de cartas y palos como números primos y multiplicarlos para representar las manos. Para pizca:

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]

Y

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

Esto daría a cada mano un valor numérico que, a través del módulo, podría decirme cuántos reyes hay en la mano o cuántos corazones. Por ejemplo, cualquier mano con cinco o más palos en ella se dividiría equitativamente por 2 ^ 5; cualquier mano con cuatro reyes se dividiría equitativamente por 59 ^ 4, etc.

El problema es que una mano de siete cartas como AcAdAhAsKdKhKs tiene un valor hash de aproximadamente 62.7 cuatrillones, lo que tomaría considerablemente más de 32 bits para representar internamente. ¿Hay alguna manera de almacenar números tan grandes en Python que me permitan realizar operaciones aritméticas en él?


88
2018-02-11 20:13


origen


Respuestas:


Python admite un tipo entero "bignum" que puede funcionar con números arbitrariamente grandes. En Python 2.5+, este tipo se llama long y está separado del int escriba, pero el intérprete utilizará automáticamente el que sea más apropiado. En Python 3.0+, el int tipo se ha caído por completo.

Sin embargo, solo se trata de un detalle de implementación: siempre que tenga la versión 2.5 o superior, solo realice operaciones matemáticas estándar y cualquier número que supere los límites de matemática de 32 bits se convertirá automáticamente (y transparentemente) en bignum.

Puedes encontrar todos los detalles sangrientos en PEP 0237.


122
2018-02-11 20:19



python apoya arbitrariamente grande enteros naturalmente:

ejemplo:

>>> 10 ** 1000 100000000000000000000000000000000000000000000000000000000000000000000000000000   000000000000000000000000000000000000000000000000000000000000000000000000000000   000000000000000000000000000000000000000000000000000000000000000000000000000000   000000000000000000000000000000000000000000000000000000000000000000000000000000   000000000000000000000000000000000000000000000000000000000000000000000000000000   000000000000000000000000000000000000000000000000000000000000000000000000000000   000000000000000000000000000000000000000000000000000000000000000000000000000000   000000000000000000000000000000000000000000000000000000000000000000000000000000   000000000000000000000000000000000000000000000000000000000000000000000000000000   000000000000000000000000000000000000000000000000000000000000000000000000000000   000000000000000000000000000000000000000000000000000000000000000000000000000000   000000000000000000000000000000000000000000000000000000000000000000000000000000   00000000000000000000000000000000000000000000000000000000000000000

Incluso podría obtener, por ejemplo, un valor entero enorme, fib (4000000).

Pero todavía lo hace no (por ahora) admite un tamaño arbitrariamente grande flotador !!

Si necesita un flotador grande, grande, luego controle el Módulo decimal. Hay ejemplos de uso en estos foros: OverflowError: (34, 'Resultado demasiado grande')

Otra referencia: http://docs.python.org/2/library/decimal.html

Incluso puede usar el módulo gmpy si necesita una aceleración (que probablemente sea de su interés): Manejo de grandes números en el código

Otra referencia: https://code.google.com/p/gmpy/


39
2018-01-07 19:50



Podrías hacer esto por diversión, pero aparte de eso no es una buena idea. No aceleraría nada de lo que pueda pensar.

  • Conseguir las cartas en una mano será una operación de factorización entera que es mucho más costosa que el simple acceso a una matriz.

  • Agregar tarjetas sería la multiplicación y la eliminación de la división de cartas, tanto de los números grandes de varias palabras, que son operaciones más caras que la adición o eliminación de elementos de las listas.

  • El valor numérico real de una mano no le dirá nada. Tendrás que factorizar los números primos y seguir las reglas del Póker para comparar dos manos. h1 <h2 para tales manos no significa nada.


27
2018-02-11 21:07



Python admite enteros arbitrariamente grandes de forma natural:

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

17
2018-02-11 20:18