WordPress如何实现保留2位小数且不发生4进5的四舍五入
问题根因
这是浮点数二进制存储的固有精度问题:类似0.1、0.01这类十进制小数无法被二进制浮点数精确表示,你执行$original_price - $sale_price得到的看似为6.84的结果,实际内部存储的是6.849999999999999或者6.839999999999999这类近似值,乘100取整再做除法的逻辑会受近似值影响出现偏差,叠加PHP输出浮点数时的默认精度处理规则,最终导致结果不符合预期。
可用解决方案
方案1:字符串截取法(最稳妥,完全规避浮点运算误差)
直接将计算结果转为固定精度的字符串,再截取前两位小数即可:
$save_price = $original_price - $sale_price; // 先转为保留10位小数的字符串,覆盖所有精度误差场景 $save_str = sprintf("%.10f", $save_price); // 匹配整数部分和前两位小数 if (preg_match('/^(\d+)\.(\d{2})/', $save_str, $matches)) { $save_price_show = "{$matches[1]}.{$matches[2]}"; } else { // 整数场景补两位0 $save_price_show = "{$save_str}.00"; } echo $save_price_show;
方案2:BC高精度运算扩展处理(PHP默认开启)
BC扩展通过字符串存储数值完成运算,完全不会出现浮点数精度丢失问题:
// 两个价格转字符串传入,计算时保留3位小数避免截断误差 $save_price = bcsub((string)$original_price, (string)$sale_price, 3); // 直接保留2位小数输出,不会自动四舍五入 $save_price_show = bcdiv($save_price, '1', 2); echo $save_price_show;
原有代码失效原因
你尝试的三段代码逻辑本质都是「乘100取整再除以100」,但因为浮点数本身是近似值,比如实际存储的$save_price为6.849999999999999时,乘100后得到684.9999999999999,部分PHP版本处理时会将该值识别为685,或是除以100后输出时被自动四舍五入为6.85,因此无法得到预期结果。
内容的提问来源于stack exchange,提问作者namari
相关产品推荐
相关产品推荐

