Remrinのpython攻略日記

python3に入門しました。python3についてあれこれとサンプルコードとか。

decimal

decimalモジュールのDecimalクラスは数値演算での誤差を回避するクラス。
 
小数の計算では誤差が生じる。

for i in range(10):
    print(i * 0.1)

# 0.0
# 0.1
# 0.2
# 0.30000000000000004
# 0.4
# 0.5
# 0.6000000000000001
# 0.7000000000000001
# 0.8
# 0.9

 
Decimalクラスを使うと

from decimal import Decimal
for i in range(10):
    print(i * Decimal("0.1"))

# 0.0
# 0.1
# 0.2
# 0.3
# 0.4
# 0.5
# 0.6
# 0.7
# 0.8
# 0.9

 
このとき、Decimalクラスに渡す引数は引用符で囲って文字列とする。
小数型のまま引数として渡すと

for i in range(10):
    print(i * Decimal(0.1))

# 0E-55
# 0.1000000000000000055511151231
# 0.2000000000000000111022302463
# 0.3000000000000000166533453694
# 0.4000000000000000222044604925
# 0.5000000000000000277555756156
# 0.6000000000000000333066907388
# 0.7000000000000000388578058619
# 0.8000000000000000444089209850
# 0.9000000000000000499600361081

なんかすごいことに。
 
Decimalクラスにはメソッドも多数ある。

d = Decimal(100)
print(d.sqrt())      # 10
print(d.is_finite()) # True
print(d.log10())     # 2

 
メソッド

adjusted() 指数部分の取り出し
as_integer_ratio() 既約分数に直す。ver3.6から
compare() 2つのDecimalインスタンスを比較し、Decimalの値で返す
copy_abs() 絶対値
copy_nagate() 符号反転
exp() 指数関数
from_fload() float型の引数を正確に表示
is_finite() 有限か
is_infinite() 無限か
is_nan() NaNか
is_zero() 0か
ln() 自然対数
log10 常用対数。底が10
quantize() 2つめと同様の丸めを行う
sqrt() 最大精度の平方根

メソッドを覚えなくても、通常のpythonの演算などが使える。
 
Decimalクラスを使った平方根いろいろ

import numpy as np
import math

d = Decimal(2)       

print(d.sqrt())               # 1.414213562373095048801688724
print(d ** Decimal("0.5"))    # 1.414213562373095048801688724
print(math.sqrt(d))           # 1.4142135623730951
print(np.sqrt(d))             # 1.414213562373095048801688724
print(pow(d, Decimal("0.5"))) # 1.414213562373095048801688724

 
9.4. decimal — 十進固定及び浮動小数点数の算術演算 — Python 3.6.1 ドキュメント