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)
函数 功能 示例 结果
math.ceil() 向上取整 ceil(3.2) 4
math.floor() 向下取整 floor(3.8) 3
math.trunc() 截断取整 trunc(-3.8) -3
math.fabs() 浮点绝对值 fabs(-3.14) 3.14
math.fmod() 浮点取余 fmod(-10.5, 3) -1.5
math.modf() 分离小数整数 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

小贴士

对于需要更高精度或复数运算的场景,可以考虑使用decimal模块(高精度十进制运算)或cmath模块(复数数学)。对于科学计算,推荐使用NumPy库,它提供向量化运算和更丰富的数学函数。


八、注意事项与最佳实践

注意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-1expm1(),计算ln(1+x)log1p()

  • 特殊值检查:在关键计算后使用math.isfinite()验证结果有效性


九、小结

  • 数学常量math.pimath.emath.taumath.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

标签: math模块 数学运算 三角函数 标准库 对数运算 阶乘组合

本文涉及AI创作

内容由AI创作,请仔细甄别

list快速访问

上一篇: Python标准库sys详解 下一篇: Python标准库random

poll相关推荐