web-dev-qa-db-ja.com

OverflowError:(34、 '結果が大きすぎます')

オーバーフローエラーが発生します(OverflowError:(34、 'Result too large')
円周率を100桁に計算したいのですが、これが私のコードです。

def pi(): 
    pi = 0 
    for k in range(350): 
        pi += (4./(8.*k+1.) - 2./(8.*k+4.) - 1./(8.*k+5.) - 1./(8.*k+6.)) / 16.**k 
    return pi 
print(pi())
16
user3033766

Python floatは任意精度ではなく、サイズも無制限です。 k = 349の場合、16.**kは大きすぎます-ほぼ2 ^ 1400です。さいわい、decimalライブラリは任意の精度を許可し、サイズを処理できます。

import decimal
decimal.getcontext().prec = 100
def pi():
    pi = decimal.Decimal(0)
    for k in range(350):
        pi += (decimal.Decimal(4)/(decimal.Decimal(8)*decimal.Decimal(k+1))...)
29
Peter DeGlopper

プラットフォームのfloatサポートの制限に達した、おそらくk = 256の後:

>>> k = 256
>>> (4./(8.*k+1.) - 2./(8.*k+4.) - 1./(8.*k+5.) - 1./(8.*k+6.)) / 16.**k
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: (34, 'Result too large')
>>> k = 255
>>> (4./(8.*k+1.) - 2./(8.*k+4.) - 1./(8.*k+5.) - 1./(8.*k+6.)) / 16.**k
3.19870064997e-313

正確な制限についてはsys.float_infoを参照してください。ただし、現在のCPUとOSの組み合わせに遭遇する可能性は低く、いずれにしても100桁の有効数字が得られます。 64ビットOS Xを搭載したMacBook Proは15のみをサポートします。

decimal module を使用して、ハードウェアの制限を超えてください。

from decimal import Decimal, localcontext

def pi(): 
    with localcontext() as ctx:
        ctx.prec = 100  # 100 digits precision
        pi = Decimal(0) 
        for k in range(350): 
            pi += (Decimal(4)/(Decimal(8)*k+1) - Decimal(2)/(Decimal(8)*k+4) - Decimal(1)/(Decimal(8)*k+5) - Decimal(1)/(Decimal(8)*k+6)) / Decimal(16)**k 
    return pi 
16
Martijn Pieters

私はpython3.6 AMD64を使用しています。これもこの問題に対応しています。これは、python組み込みfloatが倍精度浮動小数点であり、ほとんどのプログラミングタスクで64ビットだからです。 、64ビットで十分ですが、追加のタスクではそれだけでは不十分です(科学計算、ビッグデータ計算のように)

1
员建新

16。** 256は大きすぎて倍精度浮動小数点数に格納できません。とにかく、kの値が大きいと最初の100桁に寄与しないため、range(250)のようにサイクルを短くすることをお勧めします。

もう1つの方法は、16で除算する代わりに、16。* (-k)を乗算することです。 * k。この数値は、kが大きい場合はゼロに丸められるため、実行時エラーは発生しません。

**ではなくnumpy.powerを使用することをお勧めします。これにより、オーバーフローの処理が向上します。たとえば、コードでnumpy.power(16.、256)はinfと評価され、有限数をinfで除算するとゼロが得られます。これにより、前の段落で提案した方法と同様に、実行時エラーが回避されます。

1
Bence