php log() 默认以 e 为底,log(100) 返回约 4.605;需用 log(100, 10) 得常用对数 2;底数须 >0 且 ≠1,否则触发警告。

PHP log() 函数默认底数是 e,不是 10
很多人以为 log(100) 会返回 2(即以 10 为底),结果却得到约 4.605——这是因为 PHP 的 log() 默认按自然对数(底数 e)计算。这是最常踩的坑,尤其从其他语言(比如 JavaScript 的 Math.log10())转过来时容易误判。
如果要算常用对数(底数 10)、二进制对数(底数 2)或任意底数,必须显式传入第二个参数:
-
log(100, 10)→2 -
log(8, 2)→3 -
log(16, 4)→2
注意:底数必须是大于 0 且不等于 1 的正数,否则会触发警告:Warning: log(): base must be greater than 0 and not equal to 1。
换底公式在 PHP 里其实没必要手写
数学上换底公式是 log_b(a) = log_c(a) / log_c(b),但 PHP 的 log() 已原生支持双参数,直接用 log($a, $b) 就行,不用自己除。手写反而容易出错,比如:
立即学习“PHP免费学习笔记(深入)”;
- 忘记校验
$b > 0 && $b !== 1,导致运行时警告 - 对
$a 没做判断,<code>log()会返回INF或NAN(如log(-1, 10)) - 用
log($a) / log($b)计算时,若$b === 1,分母为 0,但错误发生在除法阶段,不如原生双参报错明确
性能和精度:底数用整数还是浮点数?
PHP 底数参数类型是 float,但传整数(如 10)和浮点数(如 10.0)行为一致,底层都转为 double。不过要注意两点:
- 底数接近 1(比如
1.0000001)或极小(如1e-10)时,结果可能因浮点误差失真,甚至触发数值不稳定警告 - 频繁调用时,
log($x, 10)比log10($x)稍慢一点(因为后者是专用优化函数),但 PHP 有log10()和log2()这两个快捷函数,该用就用 - 例如:
log10(1000)更清晰、略快,且语义明确;不要为了“统一写法”而弃用它们
兼容性:PHP 版本低于 5.3 时 log($a, $b) 不可用
PHP 5.2 及更早版本不支持 log() 的第二个参数,此时必须手动换底:log($a) / log($b)。但这类旧环境现在极少,除非维护遗产系统,否则无需妥协。
如果你不确定环境,可以用 function_exists('log10') 或直接测试:@log(1, 10) 是否返回 0(加 @ 抑制警告便于探测)。不过更实际的做法是:明确要求 PHP >= 7.4,避免陷入兼容性补丁泥潭。
真正容易被忽略的是边界值处理——比如 $a === 0、$a 、<code>$b === 0 这些输入,在业务逻辑里往往没做 guard,等到日志里突然冒出 NAN 才去查,比写两行判断成本高得多。











