指数函数减去 1 math.expm1()
math
模块包含 expm1()
函数,可以为非常小的 x
计算表达式 math.e ** x - 1
,其精度高于 math.exp(x)
或 cmath.exp(x)
允许:
import math
print(math.e ** 1e-3 - 1) # 0.0010005001667083846
print(math.exp(1e-3) - 1) # 0.0010005001667083846
print(math.expm1(1e-3)) # 0.0010005001667083417
# ------------------^
对于非常小的 x,差异变大:
print(math.e ** 1e-15 - 1) # 1.1102230246251565e-15
print(math.exp(1e-15) - 1) # 1.1102230246251565e-15
print(math.expm1(1e-15)) # 1.0000000000000007e-15
# ^-------------------
这种改进在科学计算中具有重要意义。例如,普朗克定律包含指数函数减 1:
def planks_law(lambda_, T):
from scipy.constants import h, k, c # If no scipy installed hardcode these!
return 2 * h * c ** 2 / (lambda_ ** 5 * math.expm1(h * c / (lambda_ * k * T)))
def planks_law_naive(lambda_, T):
from scipy.constants import h, k, c # If no scipy installed hardcode these!
return 2 * h * c ** 2 / (lambda_ ** 5 * (math.e ** (h * c / (lambda_ * k * T)) - 1))
planks_law(100, 5000) # 4.139080074896474e-19
planks_law_naive(100, 5000) # 4.139080073488451e-19
# ^----------
planks_law(1000, 5000) # 4.139080128493406e-23
planks_law_naive(1000, 5000) # 4.139080233183142e-23
# ^------------