オーバーフローエラーが発生します(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())
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))...)
プラットフォームの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
私はpython3.6 AMD64を使用しています。これもこの問題に対応しています。これは、python組み込みfloat
が倍精度浮動小数点であり、ほとんどのプログラミングタスクで64ビットだからです。 、64ビットで十分ですが、追加のタスクではそれだけでは不十分です(科学計算、ビッグデータ計算のように)
16。** 256は大きすぎて倍精度浮動小数点数に格納できません。とにかく、kの値が大きいと最初の100桁に寄与しないため、range(250)のようにサイクルを短くすることをお勧めします。
もう1つの方法は、16で除算する代わりに、16。* (-k)を乗算することです。 * k。この数値は、kが大きい場合はゼロに丸められるため、実行時エラーは発生しません。
**ではなくnumpy.powerを使用することをお勧めします。これにより、オーバーフローの処理が向上します。たとえば、コードでnumpy.power(16.、256)はinfと評価され、有限数をinfで除算するとゼロが得られます。これにより、前の段落で提案した方法と同様に、実行時エラーが回避されます。