Python math.ulp() 関数
浮動小数点数の計算において、理解すべきは浮動小数点数の精度制限であり、これは非常に重要です。ULP(Unit in the Last Place)は浮動小数点数の精度を測定する基本単位です。
math.ulp()はPython 3.9で導入された関数で、浮動小数点数の最小有効浮動小数点単位(ULP)、つまりその数値から次に表現可能な浮動小数点数までの距離を返します。
用語解説: ulp「Unit in the Last Place」の略で、「最後の桁の単位」という意味です。
基本構文とパラメータ
構文形式
import math math.ulp(x)
パラメータの説明
- x: 浮動小数点数
戻り値
xのULP値、つまりxと次に表現可能な浮動小数点数との差を返します。
例
例1:基本的な使い方
例
import math
print("1.0 の ULP:", math.ulp(1.0))
print("2.0 の ULP:", math.ulp(2.0))
print("100.0 の ULP:", math.ulp(100.0))
print("0.0 の ULP:", math.ulp(0.0))
print("最小の正数:", math.ulp(float.min)
print("1.0 の ULP:", math.ulp(1.0))
print("2.0 の ULP:", math.ulp(2.0))
print("100.0 の ULP:", math.ulp(100.0))
print("0.0 の ULP:", math.ulp(0.0))
print("最小の正数:", math.ulp(float.min)
実行結果:
1.0 的 ULP: 2.220446049250313e-16 2.0 的 ULP: 4.440892098500626e-16 100.0 的 ULP: 2.8421709430404007e-14 0.0 的 ULP: 5e-324
例2:異なる数値のULP
例
import math
values = [0.1, 0.5, 1.0, 1.5, 2.0, 10.0, 100.0, 1000.0]
print("異なる数値のULP:")
for x in values:
print(f" ULP({x}) = {math.ulp(x)}")
values = [0.1, 0.5, 1.0, 1.5, 2.0, 10.0, 100.0, 1000.0]
print("異なる数値のULP:")
for x in values:
print(f" ULP({x}) = {math.ulp(x)}")
実行結果:
不同数值的 ULP: ULP(0.1) = 1.3877787807814457e-17 ULP(0.5) = 1.3877787807814457e-16 ULP(1.0) = 2.220446049250313e-16 ULP(1.5) = 2.220446049250313e-16 ULP(2.0) = 4.440892098500626e-16 U浮点 10.0: 2.220446049250313e-15 ULP(100.0) = 2.8421709430404007e-14 ULP(1000.0) = 2.2737367544323206e-13
例3:特殊な値
例
import math
print("無限大:", math.ulp(math.inf))
print("最大有限数:", math.ulp(sys.float_info.max))
print("負数:", math.ulp(-1.0))
print("非正規化数:", math.ulp(1e-310))
print("無限大:", math.ulp(math.inf))
print("最大有限数:", math.ulp(sys.float_info.max))
print("負数:", math.ulp(-1.0))
print("非正規化数:", math.ulp(1e-310))
実行結果:
无穷大: inf 最大有限数: inf 负数: 2.220446049250313e-16 次正规数: 5e-324
例4:浮動小数点数の精度検出
例
import math
def check_precision(x):
"""浮動小数点数の精度を検出"""
ulp = math.ulp(x)
relative_error = ulp / x
print(f"x = {x}")
print(f" ULP = {ulp}")
print(f" 相対誤差 ≈ {relative_error:.2e}")
print(f" 有効桁数 ≈ {-math.log2(relative_error):.1f}")
print()
check_precision(1.0)
check_precision(1000000.0)
def check_precision(x):
"""浮動小数点数の精度を検出"""
ulp = math.ulp(x)
relative_error = ulp / x
print(f"x = {x}")
print(f" ULP = {ulp}")
print(f" 相対誤差 ≈ {relative_error:.2e}")
print(f" 有効桁数 ≈ {-math.log2(relative_error):.1f}")
print()
check_precision(1.0)
check_precision(1000000.0)
実行結果:
x = 1.0 ULP = 2.220446049250313e-16 相对误差 ≈ 2.22e-16 有效位数 ≈ 52.0 x = 1000000.0 ULP = 1.907344663e-13 相对误差 ≈ 1.91e-13 有效位数 ≈ 52.0
例5:nextafterとの組み合わせ
例
import math
# 検証:nextafter(x, inf) - x = ULP(x)
x = 1.0
next_val = math.nextafter(x, math.inf)
ulp_calc = math.ulp(x)
direct_diff = next_val - x
print(f"x = {x}")
print(f"nextafter(x, inf) - x = {direct_diff}")
print(f"math.ulp(x) = {ulp_calc}")
print(f"両者は等しい: {direct_diff == ulp_calc}")
# 検証:nextafter(x, inf) - x = ULP(x)
x = 1.0
next_val = math.nextafter(x, math.inf)
ulp_calc = math.ulp(x)
direct_diff = next_val - x
print(f"x = {x}")
print(f"nextafter(x, inf) - x = {direct_diff}")
print(f"math.ulp(x) = {ulp_calc}")
print(f"両者は等しい: {direct_diff == ulp_calc}")
実行結果:
x = 1.0 nextafter(x, inf) - x = 2.220446049250313e-16 math.ulp(x) = 2.220 double 000001e-16 两者相等: True
説明:math.ulp(x) は |nextafter(x, inf) - x| と同等です
利用シナリオ
- 数値アルゴリズムの誤差分析
- 浮動小数点数の精度検出
- 科学計算における許容差の設定
- 浮動小数点数を比較する際に適切なイプシロンを決定する
注意事項
- Python 3.9+ でのみ利用可能です
- ULP値は数値が大きくなるにつれて大きくなります
- infのULPもinfです
その他の拡張