对数函数 :指数函数的反函数
对数函数(logarithmic function) 是指数函数 的反函数( 且 )。指数函数把 送到 ,对数函数把它送回来,两条互逆的等式是 与 。
1 · 反函数关系与图象的镜像
互为反函数在几何上表现为图象关于直线 对称:指数曲线上的点 与对数曲线上的点 横纵坐标互换,两点关于 互为镜像。
定义域与值域随之互换。指数函数的定义域是 、值域是 ,对数函数正好反过来:定义域 、值域 。真数必须为正这一条不是额外规定,而是由 恒为正推出来的。对数曲线恒过定点 ,对应指数曲线过 。
单调方向则不互换,两者一致: 时同为递增, 时同为递减。这是因为反函数保持单调方向——把图象沿 翻转不改变「升」还是「降」。
常用的底有两个: 记作 ,自然底 记作 。有了换底公式,任何底的对数都能由这两者算出,所以计算器只需提供这两个键。
2 · 换底公式在浮点下不是恒等式
换底公式 在数学上是恒等式,两端是同一个实数。浮点下不是:等式两端走的是不同的计算路径,各自的舍入没有理由抵消。
最短的例子是
。原生实现 Math.log10(1000) 返回精确的 3,而按换底公式算的 Math.log(1000) / Math.log(10) 返回 2.9999999999999996,差一个 ulp。这个差别足以让 Math.log(1000) / Math.log(10) === 3 为假,而这条判等在「求
是
的几次幂」这类整数问题里是会被写出来的。
偏差的多寡与底有关,实测差得很远。取
的幂
(
从
到
),Math.log2 全部
个都返回精确的整数,而换底算法有
个不精确,最大误差
,出现在
。换成
的幂
(
从
到
),换底算法有
个不精确,比例从
跳到
(node v26.6.0)。
注 ·
这个底之所以好得多,是因为 Math.log2 通常由硬件或专门的算法直接给出,不经过一次除法;而
的幂在二进制里是精确的,取对数只需读阶码。
的幂在二进制下没有这种结构,
本身又要先舍入一次,于是分子分母各带一次误差。这也解释了 JavaScript 为何在 Math.log 之外单列 Math.log2 与 Math.log10——不是记号方便,是精度不同。
3 · 参考文献
- Logarithm. Wikipedia. 对数的定义、运算法则与换底公式。https://en.wikipedia.org/wiki/Logarithm
- Inverse function. Wikipedia. 反函数的定义、图象对称与单调方向的保持。https://en.wikipedia.org/wiki/Inverse_function
- Math.log2. MDN. 单列 为底的对数方法及其精度理由。https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log2