CC++ & Algorithm

Python中的对数和指数函数

困难2
语言版本:C++Python
概述:学习使用math库中的log、log10和exp函数,帮你理解数字的“放大”和“缩小”关系,就像用放大镜看蚂蚁和用显微镜看细菌一样神奇。

数字的“放大镜”与“缩小镜”:Python中的指数和对数函数

你有没有想过,为什么细菌会越变越多,最后多到数不清?为什么地震的震级差一级,能量就差几十倍?这些神奇的现象背后,藏着数学里的两位好朋友——指数函数和对数函数。在 Python 中,math 库帮我们把它们变成了好用的工具。指数就像让数字“快速长大”,而对数则是反过来,帮我们把一个很大的数字“缩小”回它原来的大小。


1. 指数函数 math.exp(x):让数字“一夜暴富”

指数函数 math.exp(x) 计算的是 e 的 x 次方。这里的 e 是一个特别神奇的数字,大约等于 2.71828,它在自然界中到处可见,比如细菌分裂、利滚利的利息、连蜗牛爬行的速度变化……都可以用 e 来描述。

生活中的例子:假设你有一块钱,每天利息是 100%(对,暴富的那种),那么第 1 天结束你有 2 块,第 2 天有 4 块,第 3 天有 8 块……这样增长就是指数增长。而 math.exp(1) 其实就等于 e ≈ 2.718,它描述的是连续复利下,1 块钱“一刻不停”地翻倍,一年后变成的钱数。

代码试试看

import math

# 计算 e 的 2 次方
exp_2 = math.exp(2)          # e^2 约等于 7.389
print(f"e 的 2 次方是: {exp_2:.2f}")  # 保留两位小数输出

# 计算 e 的 0 次方(任何数的 0 次方都是 1)
exp_0 = math.exp(0)
print(f"e 的 0 次方是: {exp_0}")     # 输出 1.0

# 计算 e 的 -1 次方(小于 1 的情况)
exp_neg = math.exp(-1)       # 相当于 1 / e ≈ 0.3679
print(f"e 的 -1 次方是: {exp_neg:.3f}")

你会发现,指数函数能快速“放大”一个很小的数字,也能把负数变成很小的正数。


2. 对数函数:数字的“逆向追溯”

对数是指数的逆运算,就像减法对加法、除法对乘法一样。math.log(x) 计算的是以 e 为底的对数(也叫自然对数),而 math.log10(x) 计算的是以 10 为底的对数(常用对数)。

为什么需要两种?

  • 以 10 为底的对数在生活里更常用:地震震级每增加 1,能量放大 10 倍;声音响度(分贝)也是按 log10 来算的;pH 值也是 -log10(氢离子浓度)。
  • 以 e 为底的对数则更多地出现在自然变化中,比如细菌种群的增长、放射性物质的衰变、银行存款的连续复利。

生活中的例子

  • 你用 10 元零花钱,每天翻倍(乘以 2),那么 log2(1024) = 10 告诉你经过 10 天钱就从 1 元变成了 1024 元。
  • 如果考试满分是 100 分,你想知道多少分算是“高了一个数量级”?用 log10:log10(100) = 2log10(10) = 1,说明 100 分比 10 分高了一个“10 倍档”。

代码试试看

import math

# 常用对数:以 10 为底
log10_1000 = math.log10(1000)      # 10^3 = 1000,所以结果是 3.0
print(f"log10(1000) = {log10_1000}")

# 常用对数:100 的 log10 是 2
log10_100 = math.log10(100)
print(f"log10(100) = {log10_100}")

# 自然对数:以 e 为底
ln_100 = math.log(100)             # e^4.605... ≈ 100
print(f"ln(100) = {ln_100:.2f}")   # 保留两位小数

# 自然对数:e 本身的 log 是 1
ln_e = math.log(math.e)
print(f"ln(e) = {ln_e}")           # 输出 1.0

小提示:如果你想用其他底数,比如以 2 为底,可以用 math.log(1024, 2),返回 10.0。


3. 互逆关系:像加法和减法一样默契

指数和对数是一对“冤家”——它们互相抵消。就像减法是加法的逆运算一样,exp(log(x)) 会回到 x,log(exp(x)) 也会回到 x(当然 x 必须是正数)。

验证代码

import math

# 随便选一个数
num = 50

# 先取自然对数,再指数回来
ln_num = math.log(num)           # ln(50)
back_num = math.exp(ln_num)      # e^(ln(50)) 应该等于 50
print(f"原始数字: {num}")
print(f"取对数再指数回来: {back_num:.6f}")  # 接近 50.0(可能有小误差)

# 反过来:先指数再取对数
exp_num = math.exp(3)            # e^3
log_of_exp = math.log(exp_num)   # ln(e^3) 应该等于 3
print(f"e^3 = {exp_num:.2f}, 再取对数: {log_of_exp}")  # 输出 3.0

在编程里,这种互逆关系非常有用。比如你想把一组很大的数字(像人口数量、星星的亮度)压缩到小范围显示,用对数就对了。显示的时候数据更均匀,不会出现“几百亿和零”挤在一起的尴尬。


4. 新手容易犯的错误

  • 对负数或零取对数:数学上,对数的真数必须大于 0。如果你写 math.log(-5)math.log(0),Python 会报错(ValueError 或给出 -inf)。

    # 错误示例:会报错
    # wrong = math.log(-10)   # 会提示数学域错误
    
  • 混淆 log 和 log10math.log(x) 默认是自然对数(以 e 为底),可别当成常用对数来用。比如你想算 log10(100),如果写成 math.log(100) 会得到 4.605,而不是 2.0。

  • 忘记 import math:直接写 math.exp(2) 会报 NameError,必须先 import math

  • 浮点数精度的小意外:比如 math.log(1000, 10) 得到的结果可能是 2.9999999,而不是精确的 3.0,这是因为计算机内部用二进制表示小数。但 math.log10(1000) 通常能精确返回 3.0,因为它有专门的优化。


5. 完整示例:做一个“翻倍天数计算器”

假设你的零花钱从 1 元开始,每天翻倍(乘以 2)。你想知道自己需要多少天才能攒够 1000 元?用对数就能轻松算出来。

import math

# 初始零花钱
start_money = 1.0          # 第一天有 1 元
target_money = 1000.0      # 目标金额

# 每天翻倍,相当于乘以 2,所以天数 = log2(目标/初始)
# 用换底公式:log2(x) = log(x) / log(2)
days_needed = math.log(target_money / start_money, 2)   # 以 2 为底的对数

print(f"从 {start_money} 元开始,每天翻倍,")
print(f"达到 {target_money} 元需要 {days_needed:.0f} 天。")

# 检查:2^10 = 1024,所以 1000 元大约需要 10 天(因为 2^9=512,2^10=1024)

运行结果:

从 1.0 元开始,每天翻倍,
达到 1000.0 元需要 10 天。

看,只用一行代码就算出了天数,比手动连乘快多啦!


6. 相关知识点指引

  • math.pow(x, y):通用的指数运算,计算 x 的 y 次方(但比 ** 运算符慢一点点)。
  • math.sqrt(x):平方根,实际上就是 x ** 0.5,也与指数相关。
  • cmath.log():如果你想对负数取对数(得到复数结果),可以用 cmath 库。
  • 在数据分析或科学计算中,numpy 库也提供了 np.lognp.expnp.log10,能一次性处理很多数字。

如果你对“数字的放大缩小”感兴趣,还可以去研究一下对数坐标纸分贝地震里氏震级——它们都是对数在你身边的影子。掌握了这几位“函数好朋友”,再大的数字也逃不出你的手掌心!

例题精讲

1单选题

在Python中,math.log(x)函数默认的底数是多少?

A10
Be
C2
D由参数决定
2单选题

执行math.exp(2)的结果最接近以下哪个值?

A7.389
B20.086
C2.718
D100.000
3判断题

在Python中,math.log10(100)的返回值是2.0。

4填空题
以下代码试图计算以2为底8的对数,请填空:
import math
result = math.log(___, ___)
5填空题
以下代码计算e的3次方并输出,请填空:
import math
value = math.exp(___)
print(value)