pin_drop当前位置:知识文库 ❯ 图文
Python标准库math详解
一、math模块概述
math模块是Python标准库中的数学模块,提供了访问底层C库数学函数的接口。它支持浮点数运算,包含常用的数学常量、三角函数、对数函数、指数函数、阶乘等丰富的数学工具。
代码示例
import math
# 查看math模块提供的所有函数和常量
print(dir(math))
# 查看帮助信息
help(math)
# math模块只支持实数运算,不支持复数
# 复数运算需要使用cmath模块
与内置运算符的区别:Python内置的+、-、*、/、**等运算符适用于基本的算术运算,而math模块提供更专业的数学函数,精度更高,功能更强大。
二、数学常量
math模块提供了几个常用的数学常量,这些常量具有高精度,可以直接在计算中使用。
代码示例
import math
# 圆周率 π
print(f"π = {math.pi}")
# 输出: 3.141592653589793
# 自然对数的底 e
print(f"e = {math.e}")
# 输出: 2.718281828459045
# 圆周率 τ (tau) = 2π
print(f"τ = {math.tau}")
# 输出: 6.283185307179586
# 黄金比例 φ (phi)
print(f"φ = {math.phi}")
# 输出: 1.618033988749895
# 无穷大
print(f"无穷大 = {math.inf}")
# 非数字
print(f"NaN = {math.nan}")
# 实际应用示例
def circle_area(radius):
"""计算圆面积"""
return math.pi * radius ** 2
def compound_interest(principal, rate, time):
"""计算复利(连续复利)"""
return principal * math.e ** (rate * time)
print(f"半径为5的圆面积: {circle_area(5):.2f}")
print(f"本金1000,年利率5%,10年后: {compound_interest(1000, 0.05, 10):.2f}")
三、数值操作函数
1. 取整函数
代码示例
import math
# ceil() - 向上取整
print(f"ceil(3.2) = {math.ceil(3.2)}") # 4
print(f"ceil(3.8) = {math.ceil(3.8)}") # 4
print(f"ceil(-3.2) = {math.ceil(-3.2)}") # -3
# floor() - 向下取整
print(f"floor(3.2) = {math.floor(3.2)}") # 3
print(f"floor(3.8) = {math.floor(3.8)}") # 3
print(f"floor(-3.2) = {math.floor(-3.2)}") # -4
# trunc() - 截断小数部分(向零取整)
print(f"trunc(3.8) = {math.trunc(3.8)}") # 3
print(f"trunc(-3.8) = {math.trunc(-3.8)}") # -3
# 与内置函数的对比
print(f"int(3.8) = {int(3.8)}") # 3 (截断)
print(f"round(3.5) = {round(3.5)}") # 4 (四舍六入五成双)
print(f"round(2.5) = {round(2.5)}") # 2 (银行家舍入法)
2. 绝对值与符号
代码示例
import math
# fabs() - 浮点数绝对值
print(f"fabs(-3.14) = {math.fabs(-3.14)}") # 3.14
print(f"fabs(3.14) = {math.fabs(3.14)}") # 3.14
# 与内置abs()的区别
print(f"abs(-3) = {abs(-3)}") # 3 (保持整数类型)
print(f"math.fabs(-3) = {math.fabs(-3)}") # 3.0 (始终返回浮点数)
# copysign() - 复制符号
print(f"copysign(5, -1) = {math.copysign(5, -1)}") # -5.0
print(f"copysign(-5, 1) = {math.copysign(-5, 1)}") # 5.0
print(f"copysign(3.14, -2.71) = {math.copysign(3.14, -2.71)}") # -3.14
# 实际应用:安全除法
def safe_divide(a, b):
"""安全除法,避免除以零"""
if b == 0:
return math.copysign(math.inf, a) # 根据被除数符号返回正负无穷
return a / b
print(f"10 / 0 = {safe_divide(10, 0)}") # inf
print(f"-10 / 0 = {safe_divide(-10, 0)}") # -inf
3. 取余与模
代码示例
import math
# fmod() - 浮点数取余
print(f"fmod(10.5, 3) = {math.fmod(10.5, 3)}") # 1.5
print(f"fmod(-10.5, 3) = {math.fmod(-10.5, 3)}") # -1.5
# 与%运算符的区别
print(f"10.5 % 3 = {10.5 % 3}") # 1.5
print(f"-10.5 % 3 = {-10.5 % 3}") # 1.5 (符号与除数相同)
print(f"fmod(-10.5, 3) = {math.fmod(-10.5, 3)}") # -1.5 (符号与被除数相同)
# modf() - 分离小数和整数部分
print(f"modf(3.75) = {math.modf(3.75)}") # (0.75, 3.0)
print(f"modf(-3.75) = {math.modf(-3.75)}") # (-0.75, -3.0)
四、三角函数与角度转换
1. 角度与弧度转换
代码示例
import math
# 角度转弧度
print(f"radians(180) = {math.radians(180)}") # 3.14159...
print(f"radians(90) = {math.radians(90)}") # 1.5707...
print(f"radians(45) = {math.radians(45)}") # 0.7853...
# 弧度转角度
print(f"degrees(π) = {math.degrees(math.pi)}") # 180.0
print(f"degrees(π/2) = {math.degrees(math.pi/2)}") # 90.0
# 注意:所有三角函数都使用弧度作为输入
2. 基本三角函数
代码示例
import math
# 正弦函数
print(f"sin(0) = {math.sin(0)}") # 0.0
print(f"sin(π/2) = {math.sin(math.pi/2)}") # 1.0
print(f"sin(π/6) = {math.sin(math.pi/6)}") # 0.5
# 余弦函数
print(f"cos(0) = {math.cos(0)}") # 1.0
print(f"cos(π/2) = {math.cos(math.pi/2)}") # 6.12e-17 (接近0,浮点误差)
print(f"cos(π/3) = {math.cos(math.pi/3)}") # 0.5
# 正切函数
print(f"tan(0) = {math.tan(0)}") # 0.0
print(f"tan(π/4) = {math.tan(math.pi/4)}") # 0.9999... (接近1)
# 实际应用:计算斜边长度
def hypotenuse(a, b):
"""使用三角函数计算斜边"""
angle = math.atan(b / a)
return a / math.cos(angle)
print(f"直角边3和4的斜边: {hypotenuse(3, 4):.2f}") # 5.00
3. 反三角函数
代码示例
import math
# 反正弦(返回值范围:-π/2 到 π/2)
print(f"asin(0.5) = {math.asin(0.5)}") # 0.5235... (30度)
print(f"degrees(asin(0.5)) = {math.degrees(math.asin(0.5))}") # 30.0
# 反余弦(返回值范围:0 到 π)
print(f"acos(0.5) = {math.acos(0.5)}") # 1.0471... (60度)
print(f"degrees(acos(0.5)) = {math.degrees(math.acos(0.5))}") # 60.0
# 反正切(返回值范围:-π/2 到 π/2)
print(f"atan(1) = {math.atan(1)}") # 0.7853... (45度)
print(f"degrees(atan(1)) = {math.degrees(math.atan(1))}") # 45.0
# atan2(y, x) - 计算点(x,y)与x轴的夹角
print(f"atan2(1, 1) = {math.degrees(math.atan2(1, 1))}") # 45.0
print(f"atan2(1, -1) = {math.degrees(math.atan2(1, -1))}") # 135.0
print(f"atan2(-1, -1) = {math.degrees(math.atan2(-1, -1))}") # -135.0
# 实际应用:计算两点间的角度
def angle_between_points(x1, y1, x2, y2):
"""计算从点1到点2的角度(度)"""
dx = x2 - x1
dy = y2 - y1
return math.degrees(math.atan2(dy, dx))
print(f"从(0,0)到(1,1)的角度: {angle_between_points(0, 0, 1, 1)}°")
4. 双曲函数
代码示例
import math
# 双曲正弦
print(f"sinh(1) = {math.sinh(1)}")
# 双曲余弦
print(f"cosh(1) = {math.cosh(1)}")
# 双曲正切
print(f"tanh(1) = {math.tanh(1)}")
# 反双曲函数
print(f"asinh(1) = {math.asinh(1)}")
print(f"acosh(2) = {math.acosh(2)}")
print(f"atanh(0.5) = {math.atanh(0.5)}")
# 实际应用:相对论速度叠加
def relativistic_velocity(v1, v2, c=299792458):
"""计算相对论速度叠加(m/s)"""
# v = (v1 + v2) / (1 + v1*v2/c^2)
beta1 = v1 / c
beta2 = v2 / c
# 使用双曲正切公式
return math.tanh(math.atanh(beta1) + math.atanh(beta2)) * c
# 两个0.5c的速度叠加
result = relativistic_velocity(0.5 * 299792458, 0.5 * 299792458)
print(f"两个0.5c叠加: {result / 299792458:.4f}c") # 约0.8c
五、对数与指数函数
1. 指数函数
代码示例
import math
# e的x次方
print(f"exp(1) = {math.exp(1)}") # 2.7182... (e)
print(f"exp(0) = {math.exp(0)}") # 1.0
print(f"exp(-1) = {math.exp(-1)}") # 0.3678...
# 与**运算符的对比
print(f"e**2 = {math.e ** 2}") # 7.389...
print(f"exp(2) = {math.exp(2)}") # 7.389... (更精确)
# expm1() - 计算e^x - 1(对于小x更精确)
print(f"expm1(0.00001) = {math.expm1(0.00001)}") # 0.00001000005...
print(f"exp(0.00001) - 1 = {math.exp(0.00001) - 1}") # 可能有精度损失
2. 对数函数
代码示例
import math
# 自然对数(以e为底)
print(f"log(e) = {math.log(math.e)}") # 1.0
print(f"log(1) = {math.log(1)}") # 0.0
print(f"log(100) = {math.log(100)}") # 4.6051...
# 指定底数的对数
print(f"log(100, 10) = {math.log(100, 10)}") # 2.0
print(f"log(8, 2) = {math.log(8, 2)}") # 3.0
# 以10为底的对数
print(f"log10(100) = {math.log10(100)}") # 2.0
print(f"log10(1000) = {math.log10(1000)}") # 3.0
# 以2为底的对数
print(f"log2(256) = {math.log2(256)}") # 8.0
print(f"log2(1024) = {math.log2(1024)}") # 10.0
# log1p() - 计算ln(1+x)(对于小x更精确)
print(f"log1p(0.00001) = {math.log1p(0.00001)}")
print(f"log(1.00001) = {math.log(1.00001)}")
# 实际应用:计算复利时间
def time_to_double(rate):
"""计算资金翻倍所需时间(年)"""
return math.log(2) / math.log(1 + rate)
print(f"年利率5%,翻倍需要: {time_to_double(0.05):.1f}年") # 约14.2年
六、阶乘、组合与统计函数
1. 阶乘与排列组合
代码示例
import math
# 阶乘
print(f"5! = {math.factorial(5)}") # 120
print(f"10! = {math.factorial(10)}") # 3628800
# 排列数 P(n, k) = n! / (n-k)!
print(f"P(5, 2) = {math.perm(5, 2)}") # 20
# 组合数 C(n, k) = n! / (k! * (n-k)!)
print(f"C(5, 2) = {math.comb(5, 2)}") # 10
print(f"C(52, 5) = {math.comb(52, 5)}") # 2598960 (扑克牌组合)
# 实际应用:计算彩票中奖概率
def lottery_od(total, select, match):
"""计算彩票中奖概率"""
total_combinations = math.comb(total, select)
winning_combinations = math.comb(select, match) * math.comb(total - select, select - match)
return winning_combinations / total_combinations
# 双色球头奖概率(33选6)
odds = lottery_od(33, 6, 6)
print(f"双色球头奖概率: 1/{1/odds:.0f}")
2. 最大公约数与最小公倍数
代码示例
import math
# 最大公约数
print(f"gcd(12, 8) = {math.gcd(12, 8)}") # 4
print(f"gcd(17, 13) = {math.gcd(17, 13)}") # 1 (互质)
print(f"gcd(100, 75, 50) = {math.gcd(100, 75, 50)}") # 25 (Python 3.9+)
# 最小公倍数
print(f"lcm(12, 8) = {math.lcm(12, 8)}") # 24 (Python 3.9+)
print(f"lcm(3, 4, 5) = {math.lcm(3, 4, 5)}") # 60
# 实际应用:分数化简
def simplify_fraction(numerator, denominator):
"""化简分数"""
common = math.gcd(numerator, denominator)
return numerator // common, denominator // common
print(f"24/36 化简为: {simplify_fraction(24, 36)}") # (2, 3)
3. 精确浮点求和
代码示例
import math
# fsum() - 精确浮点求和(避免精度丢失)
numbers = [0.1] * 10
print(f"sum([0.1]*10) = {sum(numbers)}") # 0.9999999999999999
print(f"fsum([0.1]*10) = {math.fsum(numbers)}") # 1.0
# 复杂示例
values = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
print(f"sum = {sum(values)}") # 5.499999999999999
print(f"fsum = {math.fsum(values)}") # 5.5
七、高级数学函数
1. 幂运算与平方根
代码示例
import math
# 幂运算
print(f"pow(2, 3) = {math.pow(2, 3)}") # 8.0 (返回浮点数)
print(f"2**3 = {2**3}") # 8 (保持整数类型)
# 平方根
print(f"sqrt(16) = {math.sqrt(16)}") # 4.0
print(f"sqrt(2) = {math.sqrt(2)}") # 1.4142...
# 立方根(使用幂运算)
def cbrt(x):
"""计算立方根"""
if x >= 0:
return x ** (1/3)
else:
return -(-x) ** (1/3)
print(f"立方根(27) = {cbrt(27):.4f}") # 3.0000
print(f"立方根(-27) = {cbrt(-27):.4f}") # -3.0000
# 实际应用:计算两点距离
def distance(x1, y1, x2, y2):
"""计算两点间欧氏距离"""
return math.sqrt((x2 - x1)**2 + (y2 - y1)**2)
print(f"(0,0)到(3,4)的距离: {distance(0, 0, 3, 4)}") # 5.0
2. 误差函数与伽玛函数
代码示例
import math
# 误差函数(统计学中常用)
print(f"erf(0) = {math.erf(0)}") # 0.0
print(f"erf(1) = {math.erf(1)}") # 0.8427...
print(f"erf(2) = {math.erf(2)}") # 0.9953...
# 互补误差函数
print(f"erfc(1) = {math.erfc(1)}") # 0.1572...
# 伽玛函数(阶乘的推广)
print(f"gamma(5) = {math.gamma(5)}") # 24.0 (等于4!)
print(f"gamma(0.5) = {math.gamma(0.5)}") # 1.7724... (等于√π)
# 对数伽玛函数(避免大数溢出)
print(f"lgamma(100) = {math.lgamma(100)}") # 对数伽玛值
# 实际应用:正态分布概率
def normal_cdf(x, mu=0, sigma=1):
"""标准正态分布累积分布函数"""
z = (x - mu) / sigma
return 0.5 * (1 + math.erf(z / math.sqrt(2)))
print(f"正态分布P(X<=1): {normal_cdf(1):.4f}") # 约0.8413
3. 判断特殊值
代码示例
import math
# 判断是否为无穷大
print(f"isinf(inf) = {math.isinf(math.inf)}") # True
print(f"isinf(-inf) = {math.isinf(-math.inf)}") # True
print(f"isinf(1.0) = {math.isinf(1.0)}") # False
# 判断是否为NaN
print(f"isnan(nan) = {math.isnan(math.nan)}") # True
print(f"isnan(1.0) = {math.isnan(1.0)}") # False
# 判断是否为有限数
print(f"isfinite(1.0) = {math.isfinite(1.0)}") # True
print(f"isfinite(inf) = {math.isfinite(math.inf)}") # False
print(f"isfinite(nan) = {math.isfinite(math.nan)}") # False
# 判断两个浮点数是否接近
print(f"isclose(1.0, 1.000000001) = {math.isclose(1.0, 1.000000001)}") # True
print(f"isclose(1.0, 1.1) = {math.isclose(1.0, 1.1)}") # False
# 实际应用:安全除法
def safe_divide(a, b):
"""安全的除法函数"""
if b == 0:
return math.nan # 返回NaN而不是抛出异常
result = a / b
if math.isinf(result):
return math.nan
return result
print(f"10/0 = {safe_divide(10, 0)}") # nan
八、注意事项与最佳实践
注意1:浮点数精度问题。由于计算机使用二进制表示浮点数,某些十进制小数无法精确表示。例如0.1 + 0.2 != 0.3。在比较浮点数时,使用math.isclose()而非==。
注意2:math模块只支持实数运算,不支持复数。如果需要对负数开平方或进行复数运算,请使用cmath模块。例如math.sqrt(-1)会抛出ValueError,而cmath.sqrt(-1)返回1j。
注意3:三角函数使用弧度而非角度。在使用sin()、cos()等函数前,务必使用math.radians()将角度转换为弧度,否则结果将不正确。
注意1:浮点数精度问题。由于计算机使用二进制表示浮点数,某些十进制小数无法精确表示。例如0.1 + 0.2 != 0.3。在比较浮点数时,使用math.isclose()而非==。
注意2:math模块只支持实数运算,不支持复数。如果需要对负数开平方或进行复数运算,请使用cmath模块。例如math.sqrt(-1)会抛出ValueError,而cmath.sqrt(-1)返回1j。
注意3:三角函数使用弧度而非角度。在使用sin()、cos()等函数前,务必使用math.radians()将角度转换为弧度,否则结果将不正确。
最佳实践总结:
-
浮点比较:使用
math.isclose()代替==比较浮点数 -
精确求和:浮点数累加使用
math.fsum()避免精度累积误差 -
角度转换:三角函数输入前使用
math.radians()转换角度 -
小值精度:计算
e^x-1用expm1(),计算ln(1+x)用log1p() -
特殊值检查:在关键计算后使用
math.isfinite()验证结果有效性
九、小结
-
数学常量:
math.pi、math.e、math.tau、math.phi等常用常量 -
数值操作:
ceil()、floor()、trunc()等取整函数 -
三角函数:
sin()、cos()、tan()及反三角函数 -
对数指数:
exp()、log()、log10()、log2() -
组合统计:
factorial()、comb()、perm()、fsum()
十、练习题
练习1
编写一个计算器函数,接收两个数字和一个运算符(+ - * / sqrt pow sin cos tan log),返回计算结果。要求:1)使用math模块的函数;2)处理除零错误;3)三角函数支持角度和弧度两种模式;4)使用math.isclose()比较浮点数结果。
练习2
编写一个统计工具函数库,包含以下功能:1)计算一组数字的平均值、中位数、方差和标准差(使用math模块);2)计算正态分布的概率密度函数值;3)使用math.fsum()进行精确求和;4)验证计算结果是否为有效数值(使用math.isfinite())。
常见问题
math模块和内置运算符有什么区别?
内置运算符(+、-、*、/、**)适用于基本算术运算,而math模块提供专业数学函数(三角函数、对数、阶乘等)。math.pow()始终返回浮点数,而**运算符会保持整数类型。对于复杂数学运算,math模块更精确、功能更丰富。
为什么0.1 + 0.2不等于0.3?
这是浮点数精度问题。计算机使用二进制表示数字,而0.1在二进制中是无限循环小数,无法精确表示。因此0.1 + 0.2实际结果是0.30000000000000004。解决方法:使用math.isclose()比较,或使用decimal模块进行精确十进制运算。
math模块支持复数运算吗?
不支持。math模块只支持实数运算。如果需要对复数进行数学运算(如对负数开平方、复数三角函数等),请使用cmath模块。cmath的API与math几乎相同,但支持复数输入和输出。
math.pow()和**运算符哪个更好?
大多数情况下推荐使用**运算符,因为它更简洁且保持类型(整数幂返回整数)。math.pow()始终返回浮点数,在需要明确浮点数结果的场景下使用。性能上两者接近,但**略快。
什么时候使用math.fsum()而不是sum()?
当对大量浮点数进行累加时,sum()会产生精度累积误差。math.fsum()使用高精度算法,结果更准确。典型场景:财务计算、科学数据处理。例如sum([0.1]*10)返回0.9999999999999999,而math.fsum([0.1]*10)返回精确的1.0。
本文涉及AI创作
内容由AI创作,请仔细甄别