bcadd/bcmul等bcmath函数只接受字符串参数,传入整数或浮点数会静默返回"0";必须显式转字符串并传$scale,比较须用bccomp(),php 8.4+才支持bcmath\number类。

bcadd/bcmul 等函数传入整数会静默失败
PHP 的 bcadd、bcmul、bcsub 等函数**只接受字符串参数**,传入 int 或 float 会导致结果为 "0" 或计算异常,且不报错。这是最常踩的坑。
- 错误写法:
bcmul(12345678901234567890, 98765432109876543210)→ 返回"0" - 正确写法:
bcmul('12345678901234567890', '98765432109876543210') - 动态值务必强制转字符串:
bcmul((string)$a, (string)$b),别依赖自动类型转换 - 注意浮点数转字符串会带科学计数法(如
1.23e4),bcmul不识别,需先用sprintf('%F', $f)格式化
小数位控制必须显式传 $scale,不能靠 bcscale()
PHP 8.3 中 bcscale() 设置的全局精度**仅对未显式传 $scale 的调用生效**;而 bcdiv() 默认 $scale = 0,不设就丢小数——这不是 bug,是设计行为。
-
bcdiv('10', '3')→"3"(不是"3.333...") -
bcdiv('10', '3', 2)→"3.33"(推荐始终显式传) -
bcscale(2); bcdiv('10', '3')→ 仍为"3",因bcdiv内部优先级高于全局设置 - 加减法可设
$scale = 0保整数,乘除建议按业务需要固定传参,避免环境差异
比较大小必须用 bccomp(),别用 == 或 strcmp
字符串数字直接用 == 比较会触发类型转换,导致溢出后误判;strcmp() 按字典序比,"10" 成立——两者都不可信。
- 错误:
'100000000000000000000' == '99999999999999999999'→ 可能转成 float 后相等 - 错误:
strcmp('100', '2')→-1(但 100 > 2) - 正确:
bccomp('100000000000000000000', '99999999999999999999', 0)→1 - 注意:
bccomp第三个参数$scale影响小数位对齐,整数比较设0即可
PHP 8.4+ 的 BcMath\Number 类在 8.3 不可用
别在 PHP 8.3 环境下尝试用 new BcMath\Number('123') 或 ->add()——这个类是 PHP 8.4 才引入的,8.3 会抛 Class not found 错误。
- 检查版本:
if (version_compare(PHP_VERSION, '8.4.0', '>=')) { /* 用 Number 类 */ } - 8.3 及更早:坚持用函数式接口
bcadd()、bcmul()等 - 若已升级到 8.4,
BcMath\Number支持运算符重载(如$a + $b),但$scale行为与函数不同:不继承bcmath.scaleini 值,且未传$scale时默认按操作数精度推导 - 混用风险高:
BcMath\Number实例不能直接传给bcadd(),会触发类型错误
字符串形态的数据一旦进入 BCMath 流程,就该全程保持字符串或 BcMath\Number(8.4+),中间掺杂整型或浮点数,溢出和精度丢失几乎必然发生。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











