在Python中处理非常大的数字

Yes*_*ke. 120 python optimization largenumber

我一直在考虑用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]
Run Code Online (Sandbox Code Playgroud)

    def HashVal(self):
      return PokerCard.facePrimes[self.cardFace] * PokerCard.suitPrimes[self.cardSuit]
Run Code Online (Sandbox Code Playgroud)

这会给每只手一个数值,通过模数可以告诉我手中有多少国王或多少颗心.例如,任何有五个或更多球杆的手将平均分为2 ^ 5; 任何有四个国王的手都会平均分为59 ^ 4等.

问题在于,像AcAdAhAsKdKhKs这样的七张牌的手的哈希值大约为62.7千万亿,内部代表需要大于32位.有没有办法在Python中存储这么大的数字,这将允许我对它进行算术运算?

Ben*_*ank 157

Python支持"bignum"整数类型,可以使用任意大数.在Python 2.5+中,此类型被调用long并与int类型分开,但解释器将自动使用更合适的类型.在Python 3.0+中,int类型已完全删除.

这只是一个实现细节 - 只要您有2.5或更高版本,只需执行标准数学运算,任何超过32位数学边界的数字都将自动(并透明地)转换为bignum.

您可以在PEP 0237中找到所有血腥细节.

  • @ IgnacioVazquez-Abrams只是澄清一点,`long`是3.0中唯一的整数类型,但它的名字叫`int`.(旧的`int`消失了.) (13认同)
  • @Mike Caron - 如果PEP 0237中列出的结构是准确的,"long`s"长度(以数字表示)存储为无符号32位整数,最多为4,294,967,295位数,这意味着它们可以轻松保持φ**(4*10)**6),这是"仅"832,951位数.但是,φ不是整数,因此您需要使用[Decimal](http://docs.python.org/library/decimal.html)(Python的浮点bignum)来计算数字.但是,您可以将结果存储在"long"中. (9认同)
  • 实际上,int和long之间的障碍在2.5中被打破.3.0完全删除int,使long成为唯一的整数类型. (3认同)
  • 问题是,使用bignum而不是32位整数对性能的影响是否超过了他所使用的聪明的手工评估方法所带来的性能优势。 (2认同)

Nun*_*eto 58

python 自然支持任意整数:

例:

>>> 10**1000 100000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000 00000000000000000000000000

你甚至可以获得一个巨大的整数值fib(4000000).

但它仍然没有(现在)支持任意大的浮动 !!

如果你需要一个大的,大的浮点数,那么检查十进制模块.这些foruns有一些使用示例:OverflowError:(34,'结果太大')

另一个参考:http://docs.python.org/2/library/decimal.html

如果您需要加速(这可能是您感兴趣的话),您甚至可以使用gmpy模块:在代码中处理大数字

另一个参考:https://code.google.com/p/gmpy/


小智 29

你可以为它的乐趣做到这一点,但除此之外,这不是一个好主意.它不会加速我能想到的任何事情.

  • 手中获取卡将是一个整数因子分解操作,这比仅访问阵列要昂贵得多.

  • 添加卡将是乘法,并且移除卡分区,两个大的多字数,这比在列表中添加或删除元素更昂贵.

  • 手的实际数值不会告诉你什么.您将需要考虑素数并遵循扑克规则来比较两手牌.h1 <h2这样的手意味着什么.


Aut*_*tic 25

python自然支持任意大整数:

In [1]: 59**3*61**4*2*3*5*7*3*5*7
Out[1]: 62702371781194950
In [2]: _ % 61**4
Out[2]: 0
Run Code Online (Sandbox Code Playgroud)

  • 这些数字并不大。 (11认同)
  • 他的例子不大,这样做,它们就很大了: &gt;&gt;&gt; 59**3*61**4*2*3*5*7*3*5*7**230 211220045596554578446376353498173001500328750765409290655906282474889602421526 59338235463661740733387628792854806889317634932394067579760484367856245790242873242914386519103447894880478531066530552121836 16484650 抱歉,我可以不能很好地格式化。 (3认同)

Hed*_*edy 9

python解释器会为你处理它,你只需要做你的操作(+、-、*、/),它就会正常工作。

int值是无限的。

做除法时要小心,默认情况下商会变成float,但float不支持这么大的数字。如果您收到一条错误消息float,说不支持这么大的数字,则意味着商太大而无法存储在float您必须使用楼层除法 ( //) 中。

它忽略小数点后的任何小数,这样,结果将为int,因此您可以获得大量结果。

>>>10//3
3

>>>10//4
2
Run Code Online (Sandbox Code Playgroud)

  • 您的答案如何解决问题中的大量问题? (4认同)