JavaScript与PHP四舍五入结果不一致?求解决办法
问题:PHP与JavaScript浮点数计算结果不一致,怎么统一?
我的PHP代码如下:
echo(number_format(22.95 * 4.1, 2));
运行结果是94.10。
但我用JavaScript试了好几种方法,结果始终是94.09,试过的代码如下:
var x = 22.95; var y = 4.10; var res = x * y; var res1 = res.toFixed(3); console.log(res); console.log(res1); console.log(Number(res1).toFixed(2)); console.log(Math.round(res * 100) / 100);
请问怎么让两者计算结果一致?
原因
22.95和4.1这两个十进制数,在计算机的二进制浮点数体系里是无限循环的,没法精确存储。它们相乘后的实际存储值,其实略小于理论上的94.095。PHP的number_format处理时,内部的精度判断会把这个接近94.095的数值四舍五入成94.10;而JavaScript直接对这个不精确的乘积做舍入,就会得到94.09。
解决办法
方法1:转成整数运算(最稳妥)
把浮点数转换成整数计算,从根源上避免浮点数精度误差:
var x = 22.95; var y = 4.10; // 把22.95转成2295(乘100),4.1转成41(乘10),相乘后除以1000(100*10),再取整 var res = Math.round((x * 100) * (y * 10) / 1000); console.log(res.toFixed(2)); // 输出 94.10
方法2:加个极小偏移量修正精度
针对这种接近临界值的情况,给乘积加一个极小的偏移量,让它刚好能触发正确的四舍五入:
var x = 22.95; var y = 4.10; var res = x * y; // 添加1e-8的偏移量,修正浮点数的精度偏差 var rounded = Math.round((res + 0.00000001) * 100) / 100; console.log(rounded.toFixed(2)); // 输出 94.10
方法3:用内置的精度常量修正
利用JavaScript内置的Number.EPSILON(表示浮点数的最小精度单位)来修正:
var x = 22.95; var y = 4.10; var res = x * y; var rounded = Math.round((res + Number.EPSILON) * 100) / 100; console.log(rounded.toFixed(2)); // 输出 94.10
内容的提问来源于stack exchange,提问作者user4095519
相关产品推荐
相关产品推荐

