反比例函数的原函数为什么是ln|x|?微积分关键推导与Python验证
如果我问你反比例函数 (y\frac{1}{x}) 的原函数是什么很多学过微积分的人会脱口而出(\ln|x|C)。但再追问一句“为什么”不少人就停在“这是公式”的层面了。尤其是当公式被写成 (\int \frac{1}{x} dx \ln|x| C) 时真正值得搞清楚的问题有三个为什么幂函数积分规则在 (n-1) 这里失效了为什么填补这个空白的偏偏是自然对数以及为什么结果必须带绝对值这个问题看起来很小但它其实是微积分里“函数类闭环”的一个关键节点。把反比例函数、指数函数、对数函数、幂函数串起来的正是导数和积分这对互逆关系。理解它不仅对数学有用对做算法、写代码、调数值积分的开发者同样重要。因为你会发现很多程序库里的log、符号计算里的integrate、数值积分里的奇异点处理都和这节课有关。我打算用一条主线来拆先看为什么 (1/x) 是幂函数积分规则里的特殊分子再证明为什么对数函数的导数恰好是 (1/x)最后用 Python 和 SymPy 做验证把容易踩的坑一次性讲清楚。1. 先搞清楚反比例函数、原函数与这个问题的真正难点反比例函数在初等数学里通常指形如 (y\frac{k}{x})(k \neq 0)的函数。当 (k1) 时就是 (y\frac{1}{x})。它的图像是双曲线在 (x0) 处不定义并且当 (x \to 0^) 时函数值趋于正无穷当 (x \to 0^-) 时函数值趋于负无穷。这两条分支分别位于第一象限和第三象限。原函数的定义也不复杂如果函数 (F(x)f(x))那么 (F(x)) 就是 (f(x)) 的一个原函数。不定积分 (\int f(x) dx) 表示 (f(x)) 的全部原函数写成 (F(x)C)。对 (y\frac{1}{x}) 来说我们要找的就是导数等于 (\frac{1}{x}) 的那个函数。真正难的地方在于这个反比例函数图像很简单可它的原函数并不是普通幂函数而是一个“新函数” (\ln|x|)。许多初学者会被这个转折绊倒明明 (1/x x^{-1})按照幂函数求积分公式不是应该得到“某个幂函数”吗为什么跑出来一个看起来完全不同的对数函数我建议先放下“背公式”的思路重新从求导的方向推导一次。因为原函数这个概念本身就是“求导的逆运算”只要你能找到一个函数它的导数确实是 (\frac{1}{x})那你就找到了原函数。接下来我们要做的就是证明 (\ln x) 和 (\ln(-x)) 的导数都等于 (\frac{1}{x})。2. 1/x 为什么是幂函数积分规则里的“例外”先回顾幂函数的求导公式[ (x^a) a x^{a-1} ]把这条公式反过来看求 (x^n) 的原函数时我们会期望[ \int x^n dx \frac{x^{n1}}{n1} C ]这个公式成立的条件是 (n \neq -1)。因为当 (n-1) 时分母 (n10)分式没有意义。有人可能会想如果硬写成 (\frac{x^0}{0})那不就是“除以 0”吗显然不行。但更深的问题在于 ((\frac{x^0}{0})) 也不等于 (1/x)。事实上 (x^0 1) 的导数是 (0)不管前面乘什么常数它都只能是 0不可能是 (1/x)。所以常规的幂函数原函数族里根本没有 (x^{-1}) 的位置必须引入一个新函数来补位。这里有一个非常有启发性的视角。积分公式里的 (\frac{x^{n1}}{n1}) 在 (n) 趋近于 (-1) 时的极限恰好能把我们引向 (\ln x)。我们这样做设 (h n1)当 (n \to -1) 时 (h \to 0)。于是从 1 到 (x) 的定积分应该是[ \lim_{h \to 0} \frac{x^h - 1}{h} ]这个极限的结果就是 (\ln x)。它是通过自然常数 (e) 的极限定义得到的所以在“幂函数通式”和“对数函数”之间并不是两条互不相干的路而是一条路的极限状态。这也解释了为什么 (n-1) 是个“临界点”它不是一个简单的空白而是一道通向对数函数的门。3. ln 的来路从指数函数反函数到自然对数既然 (1/x) 的原函数不是普通幂函数那它为什么偏偏是 (\ln x)要回答这个问题我们需要重新认识自然对数。自然对数 (\ln x) 最常见的定义是它是自然指数函数 (e^x) 的反函数。也就是说如果 (y \ln x)那么等价于 (x e^y)。这里的 (e) 是自然常数约等于 2.71828最常见的定义是[ e \lim_{n \to \infty} \left(1 \frac{1}{n}\right)^n ]从“指数函数反函数”这个定义出发我们可以很快算出它的导数。设 (y \ln x)则 (x e^y)。两边对 (x) 求导[ 1 e^y \cdot \frac{dy}{dx} ]于是[ \frac{dy}{dx} \frac{1}{e^y} \frac{1}{x} ]这个证明非常干净。它依赖的关键点是(e^x) 的导数等于它本身。而 (e^x) 的这个性质正好来自 (e) 的定义。所以说(1/x) 的原函数是对数函数不是偶然而是因为“指数函数的反函数”天然地导出了“倒数”关系。还有一本书会采取另一种定义方式直接把 (\ln x) 定义为积分[ \ln x \int_1^x \frac{1}{t} dt ]这个定义对 (x0) 成立。按照微积分基本定理积分上限函数的导数就是被积函数所以 (\ln x) 的导数等于 (\frac{1}{x})。这样一来反比例函数的原函数是对数函数几乎是定义本身的直接结果。两种定义殊途同归。不管从哪条路走你都会遇到同一个结论对数函数是“倒数关系”的积分产物。这也正是“反比例函数的原函数是 lnx”这句话背后真正的数学结构。4. 严格证明(ln x) 1/x以及为什么会出现绝对值4.1 先用反函数求导法证明前面已经写了反函数求导法的核心步骤这里把它整理成完整证明。设[ y \ln x ]则[ x e^y ]对两边关于 (x) 求导得到[ \frac{d}{dx}(x) \frac{d}{dx}(e^y) ]左边是 1右边根据链式法则是 (e^y \cdot \frac{dy}{dx})。于是[ 1 e^y \cdot \frac{dy}{dx} ]由于 (e^y x)所以[ \frac{dy}{dx} \frac{1}{x} ]这个证明只对 (x0) 有效因为 (\ln x) 本身只定义在正数区间。但它已经回答了“为什么 (1/x) 的一个原函数是 (\ln x)”。4.2 用导数定义直证如果你不想依赖反函数求导也可以直接从导数的极限定义出发。[ (\ln x) \lim_{h \to 0} \frac{\ln(xh) - \ln x}{h} ]利用对数运算法则[ \ln(xh) - \ln x \ln\left(\frac{xh}{x}\right) \ln\left(1 \frac{h}{x}\right) ]所以[ (\ln x) \lim_{h \to 0} \frac{1}{h} \ln\left(1 \frac{h}{x}\right) ]令 (t \frac{h}{x})当 (h \to 0) 时 (t \to 0)于是[ (\ln x) \frac{1}{x} \lim_{t \to 0} \frac{\ln(1t)}{t} ]这里的极限 (\lim_{t \to 0} \frac{\ln(1t)}{t} 1)正是由自然常数 (e) 的定义推出的重要极限。因此最终得到[ (\ln x) \frac{1}{x} ]这个证明虽然步骤多一些但更“原生”它没有借助 (e^x) 的导数而是直接落在“对数函数 (1/t) 的极限”上。4.3 绝对值到底从哪来很多同学会问既然上面证明的是 ((\ln x) 1/x)为什么不定积分里要写成 (\ln|x|)原因是定义域。(y\frac{1}{x}) 在 (x0) 的半轴上也是有定义的但 (\ln x) 在 (x0) 时没有意义。如果只写 (\ln x C)就把原函数限制在了 (x0) 这一半区间上丢掉了另一半。为了覆盖 (x0) 的部分我们看函数[ \ln(-x) ]对它求导使用链式法则[ \frac{d}{dx} \ln(-x) \frac{1}{-x} \cdot (-1) \frac{1}{x} ]所以 (\ln(-x)) 也是 (\frac{1}{x}) 的一个原函数只不过它定义在 (x0) 的区间上。把两种情况合并就得到了[ \ln|x| \begin{cases} \ln x, x0 \ \ln(-x), x0 \end{cases} ]因此[ \int \frac{1}{x} dx \ln|x| C ]注意这里的绝对值不是一个可有可无的装饰。如果不写绝对值就默认只在 (x0) 上成立。在 (x0) 处原函数没有定义因为 (1/x) 在该点本身不连续面积积分在这里发散不能直接跨过去。5. 用 Python/SymPy 验证原函数、导数和定积分数学推导再多也不如亲手跑一遍代码来得直观。下面我会用 Python 做三类验证符号求导、数值求导、定积分验证最后再画个图让你直观看到 (1/x) 和 (\ln|x|) 的关系。5.1 环境准备建议使用 Python 3.8 或更高版本并安装几个常用科学计算库pip install sympy scipy matplotlib numpy版本不一定要最新以你当前环境能正常安装为准。下面代码里用到的 API 都是比较稳定的常用接口。5.2 符号验证先用 SymPy 验证“对 (\ln|x|) 求导能得到 (1/x)”同时试试直接对 (1/x) 做不定积分import sympy as sp x sp.symbols(x) F sp.log(sp.Abs(x)) print(diff(log(abs(x)), x) , sp.diff(F, x)) print(integrate(1/x, x) , sp.integrate(1/x, x))运行这段代码第一行通常输出1/x。第二行在不同 SymPy 版本下的输出可能略有差异常见结果会是log(x)。这里需要提醒一个容易忽略的细节SymPy 默认把符号变量 (x) 当成复数处理所以在复数域下它更倾向于给出log(x)这种解析形式。而实数域里的严格写法是 (\log|x|)。因此不要看到integrate(1/x, x)返回log(x)就觉得“程序写错了”它和你使用的数学分支有关。对于实数域问题我们可以在心中补上绝对值或者干脆用log(abs(x))来做后续验证。5.3 数值导数验证我们把“符号求导”再换成“数值求导”用中心差分格式验证import math def F(x): return math.log(abs(x)) h 1e-7 for a in [0.5, 1.0, 2.0, -0.5, -2.0]: derivative (F(a h) - F(a - h)) / (2 * h) print(fx {a:6}: 数值导数 {derivative:.10f}, 1/x {1/a:.10f})中心差分公式是[ F(a) \approx \frac{F(ah) - F(a-h)}{2h} ]只要 (h) 足够小数值导数和 (\frac{1}{a}) 就会非常接近。特别要注意当 (a-0.5) 或 (a-2) 时(\ln|x|) 的导数仍然等于 (\frac{1}{a})这就验证了绝对值写法确实覆盖了负数区间。5.4 定积分验证再用 SciPy 的quad计算定积分和 (\ln|b| - \ln|a|) 对比from scipy.integrate import quad import math intervals [(1, 2), (0.5, 1), (-2, -1)] for a, b in intervals: val, err quad(lambda x: 1 / x, a, b) exact math.log(abs(b)) - math.log(abs(a)) print(f∫_{a}^{b} 1/x dx ≈ {val:.8f}, 精确值 {exact:.8f})这段代码会输出三个区间上的积分结果和 (\ln|b| - \ln|a|) 保持一致。这里要特别注意积分区间不能跨过 (x0)因为 (1/x) 在原点不连续、面积积分发散。如果写quad(lambda x: 1/x, -1, 1)大概率会得到无穷大或警告这正是数学上“瑕积分”要处理的边界情况。5.5 图像观察最后画一个图把反比例函数和原函数放在同一行对比import numpy as np import matplotlib.pyplot as plt x_left np.linspace(-3, -0.1, 300) x_right np.linspace(0.1, 3, 300) fig, axes plt.subplots(1, 2, figsize(10, 4)) axes[0].plot(x_left, 1 / x_left, b, labely 1/x) axes[0].plot(x_right, 1 / x_right, b) axes[0].set_title(反比例函数) axes[0].axhline(0, colorblack, lw0.8) axes[0].axvline(0, colorblack, lw0.8) axes[0].legend() axes[0].grid(True) axes[1].plot(x_left, np.log(np.abs(x_left)), r, labely ln|x|) axes[1].plot(x_right, np.log(np.abs(x_right)), r) axes[1].set_title(原函数) axes[1].axhline(0, colorblack, lw0.8) axes[1].axvline(0, colorblack, lw0.8) axes[1].legend() axes[1].grid(True) plt.tight_layout() plt.show()从图像上能看得很清楚(y\frac{1}{x}) 在原点处断开而 (y\ln|x|) 在 (x0) 和 (x0) 两侧分别定义。虽然图像也分成两支但它的导数确实处处等于对应的 (\frac{1}{x})。这和代数推导是吻合的。6. 几个连续例子从反比例函数原函数到对数运算记住“对数函数的导数是倒数”这个核心规律之后很多看上去复杂的积分都可以秒推出来。下面几个例子本质上都是 (1/x) 型积分或它的换元版本。6.1 常数倍[ \int \frac{2}{x} dx 2\ln|x| C ]这个没什么好说的常数因子直接提出来。6.2 线性换元[ \int \frac{1}{2x1} dx ]这里分母是 (2x1)分子是 1。如果我们希望把积分变成“分母分之一”需要凑出分母的导数。(2x1) 的导数是 2所以[ \int \frac{1}{2x1} dx \frac{1}{2} \int \frac{2}{2x1} dx \frac{1}{2} \ln|2x1| C ]这种“分子是分母的导数”的模式非常常见。只要乘法常数处理好结果就是对数函数。6.3 三角函数有理式再比如[ \int \cot x dx \int \frac{\cos x}{\sin x} dx ]分母是 (\sin x)分子是 (\cos x)而 (\cos x) 恰好是 (\sin x) 的导数。所以可以直接写成[ \int \cot x dx \ln|\sin x| C ]这里同样带着绝对值因为 (\sin x) 会变号而我们希望 (\ln) 的参数保持正数。这几个例子说明一个通用套路当被积函数可以写成 (\frac{g(x)}{g(x)}) 时积分结果就是 (\ln|g(x)| C)。用这个视角再看反比例函数其实这就是 (g(x)x) 的特例。所以你可以把 (\ln|x|) 看作“分母的导数在分子上”这一类积分的基础模板。7. 常见误区与易错点这一节把初学者最容易犯的错误整理成一张表方便以后排查问题。问题现象可能原因正确理解处理方式把 (\int x^{-1} dx) 写成 (\frac{x^0}{0}C)直接套用幂函数积分公式(n-1) 时公式失效使用 (\ln|x|C)只写 (\ln x C)丢掉绝对值忽略负半轴定义域(1/x) 在 (x0) 也有定义在实数域写 (\ln|x|C)认为 (\ln|x|) 在 (x0) 处有定义对对数函数定义域不清晰(\ln|x|) 在 0 处无定义原函数定义域同样排除 0定积分直接跨 0 计算把反常积分当成普通定积分(1/x) 在原点发散分段处理或讨论柯西主值忽视常数项 (C)只写出一个原函数不定积分是一族函数记得 (C)认为两个区间共用同一个 (C)默认连续区间上常数一致定义域分两支时 (C) 可以不同严格写法可分 (x0) 和 (x0) 两段其中最后一条是很多进阶学习者也会忽略的细节。由于 (1/x) 的定义域分成两个不相连的区间原函数在 (x0) 和 (x0) 上可以分别加上不同的常数。比如[ F(x) \begin{cases} \ln x 1, x0 \ \ln(-x) 5, x0 \end{cases} ]这个函数的导数仍然是 (1/x)。所以 (\int \frac{1}{x} dx \ln|x| C) 这种写法其实在“整个定义域”上并不严谨它默认了一个全局常数。不过大多数教材和工程计算都采取这种简洁写法你需要知道它背后隐含了什么但不必每次都用分段函数折磨自己。还有一个误区与程序库有关。很多语言里的log(x)只接受正数参数如果传入负数会返回NaN或抛出异常。在实际编码时如果你要处理“实数域上的对数绝对值”要写成math.log(abs(x))或np.log(np.abs(x))不要直接对负数取对数。8. 这个结论在算法与工程中的实际应用你可能会觉得一个数学公式在写业务代码时根本用不上。但事实上这个结论在机器学习、概率统计、数值计算里出现得非常频繁。最典型的是对数损失函数。逻辑回归里交叉熵损失函数包含 (\ln p) 项对参数求导时会出现 (\frac{1}{p}) 这种形式。概率 (p) 必须在 ((0,1)) 范围内所以那里不需要绝对值符号但你必须保证概率值永远大于 0。这其实就是在“对数函数的定义域”和“数值稳定性”之间做工程取舍比如实现时会给 (p) 加一个极小的eps防止出现log(0)。另一个例子是信息熵。离散熵的定义是[ H(X) -\sum_{i} p_i \ln p_i ]连续熵里面则会出现积分形式[ h(X) -\int p(x) \ln p(x) dx ]当某些概率密度函数本身包含 (\frac{1}{x}) 形式的因子时你会经常遇到 (\int \frac{1}{x} dx \ln|x|) 的变形。理解原函数结构能帮你更快判断这个积分是否收敛、是否需要拆区间。再往深处说调和级数和 (\ln n) 之间的关系也来自这里。(\sum_{k1}^n \frac{1}{k}) 的增长速度约等于 (\ln n)这正是因为 (\frac{1}{x}) 的积分是 (\ln x)。所以在做算法复杂度分析时出现“调和级数复杂度 (O(\log n))”的底层原因和反比例函数积分为对数函数完全是一回事。在数值计算里遇到 (\frac{1}{x}) 型积分时还要警惕奇异点。SciPy的quad默认会对被积函数采样如果区间跨过 0很容易计算出无穷大或发出积分不收敛的警告。工程上通常会避开奇点、拆分成左右两侧分别积分或者用更专业的反常积分方法处理。这已经不是单纯套公式的问题而是要对“原函数在哪里不存在”有清晰的感知。9. 从这个问题延伸后续可以继续学什么弄明白了“为什么反比例函数的原函数是 lnx”你其实已经打通了一条理解微积分的主线幂函数、指数函数、对数函数之间通过导数和积分形成了闭环。下一步可以从这个点继续向外延伸。第一个方向是学习更多“不同类型原函数”的例子。比如[ \int \frac{1}{x^21} dx \arctan x C ]这里出现的是反三角函数背后的逻辑和 (\ln|x|) 很相似当被积函数不能用普通幂函数解决时新函数就会出现。理解 (1/x) 的对数原函数就是理解这一整类“原函数扩张”的基础。第二个方向是复变函数。在实变量下(\int 1/x dx \ln|x| C) 需要分段讨论绝对值但在复变量下对数函数 (\log z) 是多值的绝对值不再是主角。你会在复分析里重新见到这个公式感受会很不一样。第三个方向是反常积分和柯西主值。(1/x) 在 (x0) 处发散那么 (\int_{-1}^{1} \frac{1}{x} dx) 到底等于多少如果按对称性“抵消”有人说等于 0但严格按黎曼积分的定义它并不收敛。这种边界问题在信号处理和概率论中都可能突然冒出来值得提前了解。回到最初的问题不要只记 (\ln|x|C)而是理解“为什么”。因为这个看似简单的公式背后连接着极限、导数、积分、定义域、数值稳定性等一系列技术判断。对于经常写代码的开发者来说这种“从数学到工程”的迁移能力往往比公式本身更值钱。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →