web-dev-qa-db-ja.com

Pythonでの非常に大きな数の処理

Pythonでの高速ポーカーハンド評価を検討しています。処理を高速化する1つの方法は、すべてのカードのフェイスとスーツを素数で表し、それらを掛け合わせてハンドを表すことだと思いました。聖霊降臨祭に:

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人の王を持つ手は59 ^ 4などで均等に分割されます。

問題は、AcAdAhAsKdKhKsのような7枚のカードのハンドが約62.7兆のハッシュ値を持っていることです。これは、内部的に表現するのに32ビットよりもかなり多くかかります。そのような大きな数をPythonに格納する方法はありますか?

113

Pythonは、「bignum」整数型をサポートします。これは、任意の大きな数で動作できます。 Python 2.5+では、このタイプはlongと呼ばれ、intタイプとは異なりますが、インタープリターはより適切な方を自動的に使用します。 Python 3.0+では、intタイプは完全に削除されました。

ただし、これは実装の詳細にすぎません。バージョン2.5以上があれば、標準の数学演算を実行するだけで、32ビット数学の境界を超える数値は自動的に(透過的に)bignumに変換されます。

PEP 0237 ですべての血みどろの詳細を見つけることができます。

152
Ben Blank

pythonサポート任意にlarge整数自然:

例:

>>>** 1000年10 100000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000 00000000000000000000000000000000000000000000

たとえば、巨大な整数値fib(4000000)を取得することもできます。

しかし、まだnot(今のところ)任意の大きさのfloatをサポートしています!!

大きくて大きなフロートが必要な場合は、decimalモジュールを確認してください。これらのフォーラムでの使用例があります: OverflowError:(34、 'Result too large')

別のリファレンス: http://docs.python.org/2/library/decimal.html

スピードアップが必要な場合はgmpyモジュールを使用することもできます(これはあなたの興味の対象になる可能性が高い): コード内の大きな数の処理

別の参照: https://code.google.com/p/gmpy/

52
Nuno Aniceto

あなたはそれの楽しみのためにこれを行うことができますが、それ以外はそれは良いアイデアではありません。それは私が考えることができるものをスピードアップしないでしょう。

  • カードを手に入れることは整数の因数分解操作であり、単に配列にアクセスするよりもはるかに高価です。

  • カードを追加すると乗算が行われ、カード分割が削除されます。どちらも大きなマルチワード番号であり、リストに要素を追加または削除するよりも高価な操作です。

  • ハンドの実際の数値では何もわかりません。プライムを因数分解し、ポーカーのルールに従って2つのハンドを比較する必要があります。そのようなハンドのh1 <h2は何も意味しません。

29
Tom

pythonは自然に任意の大きな整数をサポートします:

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