为什么PHP的round()传入变量和硬编码同值返回结果不同?
PHP中两次round调用返回结果不一致原因
核心原因是IEEE 754浮点数二进制存储的固有精度误差,PHP的浮点数采用双精度64位格式存储,无法精确表示所有十进制小数,你肉眼看到的打印值不等于变量在内存中的实际存储值。
具体差异分析
- 变量
$ppp的实际存储值并非精确的5.585:
你用echo $ppp得到的5.585是PHP为了提升可读性自动做了截断/友好格式化后的输出,不是真实值。你可以用printf("%.20f", $ppp)打印高精度小数位,会发现它的实际值略大于5.585,通常是5.58500000000000102318这类数值,做舍入时大于等于5.585的临界值,所以得到5.59。 - 硬编码的5.585实际存储值略小于5.585:
十进制的5.585本身就无法被二进制浮点数精确表示,硬编码写入的5.585在内存中实际存储值类似5.58499999999999874124,低于5.585的临界值,配合PHP_ROUND_HALF_EVEN(银行家舍入规则,逢五看前一位奇偶性,偶数舍奇数入)的逻辑,就会得到5.58。
验证代码
你可以运行以下代码查看两个值的真实存储精度:
$price = 75.3975; $ppp = $price - ($price/(1.08)); // 打印20位小数查看真实存储值 printf("ppp实际存储值:%.20f\n", $ppp); printf("硬编码5.585实际存储值:%.20f\n", 5.585);
解决方案
涉及金额等对精度要求高的场景,不要直接用PHP原生浮点数运算,建议使用BC Math高精度运算扩展处理,避免精度误差。
内容的提问来源于stack exchange,提问作者HOY
相关产品推荐
相关产品推荐

