PHP json_encode处理整数时自动添加小数的精度异常问题咨询
问题结论
你的测试不存在误差,该现象是双精度浮点数精度限制导致的正常表现,不是json_encode函数的逻辑bug。
产生原因
- 首先是
json_encode的默认处理逻辑:当PHP运行环境为32位、或调用时未传入JSON_BIGINT_AS_STRING参数时,超过平台整型存储上限的大整数会被自动转换为双精度浮点数(double类型)后再做编码处理。 - 双精度浮点数的固有精度限制:双精度浮点数仅用52位存储有效数字,对应十进制的有效精度为15~17位,无法精确表示所有整数。你测试的125398460000转换为二进制浮点数时没有对应精确值,内存中存储的近似值换算回十进制就是125398459999.99998。
- 相邻数值无异常的原因:浮点数的可精确表示值是离散分布的,相邻整数和浮点数可表示值的偏差大小随机。你测试的125398460001、125398470000两个值,和最近的可精确表示浮点数的偏差极小,转换回十进制输出时会被自动四舍五入为原始整数值,误差不会暴露;只有125398460000刚好落在偏差阈值上,才会显示出精度损失的结果。
修复方案
- 涉及大整数编码场景,调用
json_encode时传入JSON_BIGINT_AS_STRING参数,将大整数按字符串类型编码,从根本上避免浮点数转换的精度损失,示例代码:
$value = 125398460000; // 传入参数后编码结果为字符串类型的"125398460000",无精度损失 echo json_encode($value, JSON_BIGINT_AS_STRING);
- 业务中如果使用大整数作为ID、订单号等场景,建议从数据源读取时就按字符串类型存储,不要赋值为整型变量,避免PHP自动做类型转换产生精度问题。
内容的提问来源于stack exchange,提问作者rurumita
相关产品推荐
相关产品推荐

