在 Python 中处理非常大的数字

发布于 2024-07-13 16:36:44 字数 646 浏览 5 评论 0原文

我一直在考虑用 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]

这将为每手牌提供一个数值,通过模数可以告诉我手中有多少个国王或有多少颗红心。 例如,任何拥有 5 个或更多梅花的手牌都会除以 2^5; 任何有 4 个 K 的手牌都会被 59^4 平分,等等。

问题是,像 AcAdAhAsKdKhKs 这样的七张牌手牌的哈希值约为 62.7 千万亿,这将需要远远超过 32 位的内部表示。 有没有一种方法可以在 Python 中存储如此大的数字,以便我对其执行算术运算?

I've been considering fast poker hand evaluation in Python. It occurred to me that one way to speed the process up would be to represent all the card faces and suits as prime numbers and multiply them together to represent the hands. To whit:

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]

AND

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

This would give each hand a numeric value that, through modulo could tell me how many kings are in the hand or how many hearts. For example, any hand with five or more clubs in it would divide evenly by 2^5; any hand with four kings would divide evenly by 59^4, etc.

The problem is that a seven-card hand like AcAdAhAsKdKhKs has a hash value of approximately 62.7 quadrillion, which would take considerably more than 32 bits to represent internally. Is there a way to store such large numbers in Python that will allow me to perform arithmetic operations on it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

︶ ̄淡然 2024-07-20 16:36:44

Python 支持“bignum”整数类型,可以处理任意大的数字。 在Python 2.5+中,这种类型称为long,与int类型分开,但解释器会自动使用更合适的类型。 在 Python 3.0+ 中,int 类型已被完全删除。

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

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

Python supports a "bignum" integer type which can work with arbitrarily large numbers. In Python 2.5+, this type is called long and is separate from the int type, but the interpreter will automatically use whichever is more appropriate. In Python 3.0+, the int type has been dropped completely.

That's just an implementation detail, though — as long as you have version 2.5 or better, just perform standard math operations and any number which exceeds the boundaries of 32-bit math will be automatically (and transparently) converted to a bignum.

You can find all the gory details in PEP 0237.

拥抱没勇气 2024-07-20 16:36:44

Python 自然支持任意整数

示例:

>>> 10**1000
10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

例如,您甚至可以获得一个巨大的整数值,纤维蛋白(4000000)。

但它仍然(目前)支持任意大的浮动

如果您需要一个很大的浮点数,请检查小数模块。 此网站上有使用示例:OverflowError: (34, '结果太大' )

另一个参考:9.4。 十进制 - 十进制定点和浮点算术

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

另一个参考:gmpy (Google 代码

Python supports arbitrarily large integers naturally:

Example:

>>> 10**1000
10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

You could even get, for example, a huge integer value, fib(4000000).

But still it does not (for now) supports an arbitrarily large float!!

If you need one big, large, float then check up on the decimal Module. There are examples of use on this site: OverflowError: (34, 'Result too large')

Another reference: 9.4. decimal — Decimal fixed point and floating point arithmetic

You can even using the gmpy module if you need a speed-up (which is likely to be of your interest): Handling big numbers in code

Another reference: gmpy (Google Code. Read-only)

坏尐絯℡ 2024-07-20 16:36:44

你可以为了好玩而这样做,但除此之外,这不是一个好主意。 它不会加速我能想到的任何事情。

  • 获取手中的牌将是一个整数因式分解操作,这比仅仅访问数组要昂贵得多。

    获取手中的牌

  • 添加卡片将是乘法,删除卡片除法,两者都是大型多字数字,这比在列表中添加或删除元素更昂贵的操作。

  • 一手牌的实际数值不会告诉你任何信息。 您需要分解质数并遵循扑克规则来比较两手牌。 h1 < 对于这样的牌,h2 没有任何意义。

You could do this for the fun of it, but other than that it's not a good idea. It would not speed up anything I can think of.

  • Getting the cards in a hand will be an integer factoring operation which is much more expensive than just accessing an array.

  • Adding cards would be multiplication, and removing cards division, both of large multi-word numbers, which are more expensive operations than adding or removing elements from lists.

  • The actual numeric value of a hand will tell you nothing. You will need to factor the primes and follow the Poker rules to compare two hands. h1 < h2 for such hands means nothing.

皓月长歌 2024-07-20 16:36:44

Python 自然支持任意大的整数:

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

In [2]: _ % 61**4
Out[2]: 0

Python supports arbitrarily large integers naturally:

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

In [2]: _ % 61**4
Out[2]: 0
帅的被狗咬 2024-07-20 16:36:44

Python 解释器将为您处理它。 您只需执行您的操作(+、-、*、/),它就会正常工作。

int 值是无限的。

做除法时要小心。 默认情况下,商会转换为 float,但 float 不支持这么大的数字。 如果您收到一条错误消息,指出 float 不支持如此大的数字,则意味着商太大而无法存储在 float 中,您必须使用下限除法(<代码>//)。

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

>>>10//3
3

>>>10//4
2

The Python interpreter will handle it for you. You just have to do your operations (+, -, *, /), and it will work as normal.

The int value is unlimited.

Be careful when doing division. By default, the quotient is turned into float, but float does not support such large numbers. If you get an error message saying float does not support such large numbers, then it means the quotient is too large to be stored in float you’ll have to use floor division (//).

It ignores any decimal that comes after the decimal point, this way, the result will be int, so you can have a large number result.

>>>10//3
3

>>>10//4
2
明媚如初 2024-07-20 16:36:44

为什么你想要这样做? 如果您坚持将手存储为单个编码值而不是字典或列表,请使用位字符串而不是素数的乘积。 乘法和素数分解很慢

将每张卡编码为 2 的幂(1、2、4、8、16 等)。 您可以使用hand |= card添加一张牌。 您可以使用if hand & 检查一张牌。 卡> 0 。

Why would you ever want to do this? If you insist on storing the hand as a single encoded value instead of a dict or list use a bit-string instead of the product of primes. Multiplication and prime number factorization is slow.

Encode each card as a power of 2 (1, 2, 4, 8, 16, etc.). You can add a card with hand |= card. You can check for a card with if hand & card > 0.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文