使用方法
- 在「数值 x」里填一个大于 0 的十进制数,页面默认填好示例 1000;「底数」下拉默认选中常用对数(底 10),也可以切到自然对数 e、二进制对数 2,或选「自定义底数」后在旁边的输入框里填任意大于 0 且不等于 1 的底数。
- 点「计算」,结果区给出主结果 log 底 b 的 x,下面依次是计算路径(内置函数还是换底)、自然对数 ln x、常用对数 lg x、二进制对数 log2 x、换底中间量 ln x、换底中间量 ln b、换底结果 ln x ÷ ln b(与主结果对比),以及反算校验 b 的 y 次方。底数恰好是 e、10、2 时主结果走内置函数,对比行则显示换底结果,两者通常只差最后一位。
- 在任一输入框里按 Enter 立即重算;改动下拉框或自定义底数也会自动重算,不需要再点按钮。
- 下方对照表列出 24 个常用数值的 ln、lg、log2,默认显示 12 行,点「加载更多」每次再放 12 行。点「复制对照表」得到制表符分隔的文本,点「导出对照表 CSV」下载带 UTF-8 BOM 的表格文件。
- 点「载入示例」把数值与底数恢复成 1000 与 10,并重新算一遍。
这个对数计算器能解决什么问题
一是把三种常用对数一次算齐。物理题里常要 ln,工程估算题里常要 lg,算法复杂度题里常要 log2;本页一次把这三个结果并列出来,省掉了在中途换算底数的步骤,也避免了「换错底」这类低级错误。
二是算出任意底数的对数值。计算机与计算器通常只提供自然对数和常用对数两把钥匙,需要 log 底 3、log 底 7 这类结果时,必须用换底公式绕一步;本页把这一步做成输入框,直接给结果并显示中间量。
三是核对教材、试卷或程序里的对数结果。做实验数据处理时,理论值与人手算的值差一点点很常见,本页同时给出换底中间量和反算值,可以判断差异来自四舍五入、底数取错,还是真的算错了。
四是排查换底公式写反的代码。把 Math.log(x) / Math.log(b) 写成 Math.log(b) / Math.log(x) 是最常见的一种错,两者的结果互为倒数、在 b 与 x 接近时数值差别不大,肉眼很难发现;本页可以拿一组具体数值快速对照。
本页不做这些事:不做幂运算与开方的专门计算(那是反方向的工具)、不做对数坐标图的绘制、不做复数对数(需要实部加虚部的表示法,本页只在说明里解释为什么它超出实数范围)。
原理和变量:Math.log、Math.log10 与换底公式
这个对数计算器的计算内核是 ECMAScript 标准里的三个数学函数:Math.log(x) 返回自然对数(底为 e ≈ 2.718281828459045),Math.log10(x) 返回常用对数(底为 10),Math.log2(x) 返回二进制对数(底为 2)。三者都接受一个 Number 参数、返回 Number。
最容易踩的坑是名字。很多语言的 log() 是常用对数,而 JavaScript 的 Math.log() 是自然对数;把 Math.log(1000) 当成 lg 会得到 6.907755278982137,而正确答案 3 差了一倍多。Math.LN10 是常量 2.302585092994046、Math.LN2 是 0.6931471805599453、Math.LOG10E 是 0.4342944819032518、Math.LOG2E 是 1.4426950408889634,换底时常直接引用。
任意底数走换底公式。数学上 log 底 b 的 x 等于 ln x ÷ ln b,翻译成代码就是 Math.log(x) / Math.log(b)。中间量一共两个:分子 Math.log(x) 与分母 Math.log(b),本页把这两个值都显示出来,方便核对。也可以换成 Math.log10(x) / Math.log10(b) 或 Math.log2(x) / Math.log2(b),数学上等价,浮点结果可能差最后一位。
为什么内置 log10 往往比换底更准。换底要算两次对数再相除,两次的舍入误差会叠加;内置 Math.log10 是一次逼近,通常更接近真值。实测 x = 1000、底 10 时,Math.log10(1000) 精确返回 3,而 Math.log(1000) / Math.LN10 得到 2.9999999999999996,两者相差 4.440892098500626e-16。所以能用内置函数就用内置函数,需要非 2、非 10、非 e 的底数时再换底。
反算校验是最后一道闸。把结果 y 代回去算 Math.pow(b, y),正常情况下应该回到 x 附近(例如 10 的 3 次方等于 1000);差得远说明底数或数值填错了。ECMAScript 还规定 Math.log10 属于「实现近似」函数,即各引擎的最后一个二进制位允许有差异,跨平台比对时不要卡到小数点后 15 位。
完整示例:x = 1000、底数 10
示例条件就是页面打开时的默认状态:数值 1000、底数 10。此时主结果 log 底 10 的 1000 等于 3,也就是 10³ = 1000 的逆运算。因为底数正好是 10,本页走的是内置 Math.log10 这条一次逼近路径(结果区第一行会标明),所以主结果精确是 3。下面把每一步的中间量列出来,可以和结果区逐项对照:
- 自然对数
Math.log(1000)= 6.907755278982137 - 常用对数
Math.log10(1000)= 3(本页主结果) - 二进制对数
Math.log2(1000)= 9.965784284662087 - 换底中间量
Math.log(1000) / Math.LN10= 2.9999999999999996,与内置函数相差 4.440892098500626e-16,只差最后一位 - 反算校验
Math.pow(10, 3)= 1000,完全回到原值 - 常量
Math.LN10= 2.302585092994046,它正是 ln 10 的值
把同一个 1000 换成其它底数:底 2 时 log2(1000) = 9.965784284662087,底 e 时就是自然对数 6.907755278982137;换成底 3 则用换底算得 6.2877098228681545,反算 3 的 6.2877098228681545 次方得到 1000.0000000000008,与 1000 只差 8e-13。数值仅作演示,它们只由 x 与底数决定,与显示格式无关。
输入范围与常用数值对数对照表
数值 x 的可用范围是大于 0 且不超过 1.7976931348623157e308(双精度能表示的最大值),负数和 0 都会被拦下并给出具体提示。底数 b 的范围是大于 0 且不等于 1,可以取 0.5 这样的小数。下表列出十个代表性数值的三个对数值,取六位小数。
| x | ln x | lg x | log2 x |
|---|---|---|---|
| 0.1 | −2.302585 | −1 | −3.321928 |
| 0.5 | −0.693147 | −0.301030 | −1 |
| 1 | 0 | 0 | 0 |
| 2 | 0.693147 | 0.301030 | 1 |
| 2.718281828 | 1 | 0.434294 | 1.442695 |
| 10 | 2.302585 | 1 | 3.321928 |
| 100 | 4.605170 | 2 | 6.643856 |
| 1000 | 6.907755 | 3 | 9.965784 |
| 10000 | 9.210340 | 4 | 13.287712 |
| 1000000 | 13.815511 | 6 | 19.931569 |
从表里能看出两个恒定规律:无论 x 取多少,lg x 与 ln x 的比值恒等于 log10(e) ≈ 0.4342944819032518(也就是 Math.LOG10E),log2 x 与 ln x 的比值恒等于 log2(e) = 1.4426950408889634(也就是 Math.LOG2E)。上方的动态对照表把数值扩展到 24 个,包含 1e12、1e100 与双精度的两个极端值。
边界与精度:定义域、负底数与 Math.log1p
- x = 0 得到负无穷,不是报错。按 IEEE 754 与 ECMAScript 的规定,
Math.log(0)与Math.log10(0)都返回-Infinity,因为 0 的对数在极限意义下趋向 −∞;Math.log(-0)同样返回 −Infinity。本页把 0 直接判为非法输入,是为了避免把 −∞ 当成一个「结果」继续往下算。 - x 为负数时返回 NaN。
Math.log(-1)是NaN,不是 −0 也不是虚数。真要求 ln(−1),答案是虚数 iπ(因为 e 的 iπ 次方等于 −1,这就是欧拉恒等式),但它要求把数字扩成「实部 + 虚部」两个分量,JavaScript 的 Number 装不下,所以本页只给出「实范围内无定义」的提示。 - 底数不能等于 1,也不能小于等于 0。换底公式的分母是 ln b:b = 1 时 ln 1 = 0,除法变成除以零,所以 log 底 1 的 x 对任何 x ≠ 1 都无解;b ≤ 0 时 ln b 在实数范围无定义,负数底数同样要进复数域(例如 ln(−2) = ln 2 + iπ)。本页对这两种情况分别给出提示文案。
- x 极小时必须换用 Math.log1p,否则精度全丢。
Math.log1p(x)直接按 ln(1 + x) 计算,绕开了先做1 + x这一步的舍入。实测 x = 1e-16 时,Math.log(1 + x)先把 1e-16 舍进 1,结果返回 0,相对误差 100%;而Math.log1p(1e-16)返回 1e-16,相对误差为 0。x = 1e-15 时两者相对误差还有 11.02%。临界点在Number.EPSILON= 2.220446049250313e-16:小于它的一半,1 + x会被直接舍回 1。 - 双精度能表示的极值也有确定的对数。
Math.log(Number.MAX_VALUE)= 709.782712893384,Math.log10是 308.25471555991675,Math.log2是 1024;Math.log(Number.MIN_VALUE)(约 5e-324,最小的非零正数)= −744.4400719213812。所以任意合法 x 的对数都落在 −744.45 与 709.79 之间,不会溢出。 - 换底与内置函数的差异只在小数点后十几位。前面实测的 4.440892098500626e-16 就是这个量级。做工程估算时完全不必在意;只有在写数值库、做跨平台逐位比对时,才需要记住
Math.log10与Math.log2在标准里是「实现近似」的,不同引擎最后一位可能不同。
常见问题
ln、lg、log 到底哪个是哪个?
ln 是自然对数,底为 e ≈ 2.718281828459045;lg 是常用对数,底为 10;在算法与信息论里 log 常指底 2。JavaScript 里对应的三个函数是 Math.log(自然对数)、Math.log10、Math.log2。注意 Math.log 是自然对数,不是常用对数,这是最容易记反的一处。
为什么换底算 log10(1000) 得到 2.9999999999999996,而不是 3?
换底要先算 ln 1000 与 ln 10 两次逼近再相除,两次舍入误差叠加,最后一位偏了 4.440892098500626e-16。内置的 Math.log10(1000) 是一次逼近,精确返回 3。需要底 10 时直接用 Math.log10 即可,换底留给非 2、非 10、非 e 的底数。
为什么输入 0 或负数会被拦下?
因为实数范围内的对数只在 x > 0 时有定义。Math.log(0) 返回 −Infinity,Math.log(−1) 返回 NaN,都不是可以继续参与计算的数;负数真正的对数落在复数域(ln(−1) = iπ),需要两个分量表示,本页不处理。
底数填 1 或者负数可以吗?
不行。换底公式的分母 ln b 在 b = 1 时等于 0,除法无意义;b 为负数时 ln b 在实数范围无定义。底数必须大于 0 且不等于 1,像 0.5、2、7、100 都可以。
Math.log1p 是干什么用的?
它直接算 ln(1 + x),避免先做 1 + x 时把极小的 x 舍掉。x = 1e-16 时 Math.log(1 + x) 返回 0,而 Math.log1p(1e-16) 返回 1e-16。凡是计算「微小变化率」「复利中的小利率对数」这类场景,都应该用 Math.log1p。
输入很大的数结果还对吗?
对。只要不超过 1.7976931348623157e308,双精度都能装下,对应的自然对数最大约 709.78、以 2 为底最大 1024,远没有溢出风险。超过上限的输入会被 Number 变成 Infinity,本页会提示超出双精度范围。
「复制对照表」和「导出对照表 CSV」有什么区别?
前者把对照表以制表符分隔的文本写进剪贴板,粘进 Excel 会自动分列;后者下载一个开头带 UTF-8 BOM 的 .csv 文件,双击用 Excel 打开不会中文乱码。两者内容一致。
输入的数值会传到服务器吗?
不会。这个对数计算器的全部运算都在当前页面的脚本里完成,用的是浏览器内置的 Math 函数,全程没有网络请求,也不写浏览器存储。打开开发者工具的 Network 面板边算边看,不会有新请求发出。