Pythonのrange関数をfloat型に拡張してみた
Abstract
Pythonのrange関数はInt型しか扱えない。0.1 ステップ刻みのようなfloat型でも同じことをやりたかったので、作ってみた。
Introduction
Pythonのrange関数は、整数値にしか使えない。 float型でやろうとするとnumpyのarrange関数を使うという手があるが、そのためだけに "import numpy"するのも気が引ける。
検索すると、以下のような関数を自分で定義するというのが割と知られているらしい。
def frange(start, end, step): for i in range(int((end-start)/step)): yield start + i*step
が、これを実際につかってみると、丸め誤差の影響が出るのであまり美しくない。
for f in frange(1.3, 2.1, 0.1): print(f) #1.3 #1.4000000000000001 #1.5 #1.6 #1.7000000000000002 #1.8 #1.9000000000000001 #2.0
やりたいこと
float型に拡張したrange関数で、かつ、丸め誤差が乗らないようなものを作りたい。
コードと実行結果
from decimal import Decimal def drange(start, end, step): start = Decimal(str(start)) end = Decimal(str(end)) step = Decimal(str(step)) for i in range(int((end-start)/step)): yield float(start + i*step)
for f in drange(1.3, 2.1, 0.1): print(f) #1.3 #1.4 #1.5 #1.6 #1.7 #1.8 #1.9 #2.0
Conclusion
今回は、一度Decimal型に内部で変換して扱うことで丸め誤差を抑えた。 Pythonの標準ライブラリの一部なので、numpyのようにインストールせずとも使えるのがメリット。