PHP解析JSON浮点数“精度丢失”实为显示、序列化或类型转换偏差:一、大整数用JSON_BIGINT_AS_STRING转字符串;二、小数位简化需sprintf格式化为字符串;三、浮点运算误差应改用整型或BCMath;四、调试须检查json_encode输出及前后端数据类型。

PHP解析JSON时浮点数“精度丢失”,多数情况不是真丢了,而是显示、序列化或类型转换环节出了偏差。关键要分清:是数值计算失真?还是小数位被省略?或是大整数变科学计数法?不同现象对应不同解法。
一、json_decode时大整数变float(ID、时间戳等被截断)
典型表现:JSON里明明是"id": 8559795009588101021,json_decode($json, true)后变成8.5597950095881E+18或近似浮点值——这是64位浮点无法精确表示超大整数导致的。
- ✅ 正确解法:用
JSON_BIGINT_AS_STRING选项,强制把超长数字当字符串处理 json_decode($json, true, 512, JSON_BIGINT_AS_STRING)- ⚠️ 注意:该选项只影响整数,对
12.34这类浮点数无效
二、json_encode输出小数位被简化(如12.3400 → 12.34)
这不是精度丢失,是JSON规范不保存格式信息,PHP默认输出最简形式。前端看到“12.34”就以为少了两位零,其实数值没变,只是显示省略了冗余零。
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
- ✅ 稳妥做法:提前格式化为字符串,再进JSON
-
['price' => sprintf('%.2f', $price)]→ 输出{"price":"12.34"} - ? 补零逻辑:
sprintf('%.4f', 12.3)得"12.3000";sprintf('%.4f', 12.34567)得"12.3457"(四舍五入) - ? 避免用
(string)$float,它受precision配置影响,不可控
三、浮点运算本身引入误差(如0.1 + 0.2 = 0.30000000000000004)
这是IEEE 754双精度浮点的固有局限,所有语言都存在。PHP里一旦参与运算,误差就会带入后续环节。
立即学习“PHP免费学习笔记(深入)”;
- ✅ 金融类场景:统一用“分”存整型,彻底绕开浮点
- ✅ 高精度计算:用BCMath扩展,如
bcadd('0.1', '0.2', 1) - ✅ 接收外部JSON含高精度数字时,先用
JSON_BIGINT_AS_STRING,再按需用bcadd等处理
四、调试与验证要点
别只信var_dump()或print_r()——它们可能掩盖问题。真正要看数据流出环节:
- 检查
json_encode()原始输出字符串,确认是否已失真 - 查看数据库字段类型:如果是
DECIMAL(10,2),入库前就应确保是字符串或整型 - 前端拿到JSON后,用
typeof data.price === 'number'判断是否被转成JS number(同样有精度限制) - 关键字段(price/amount/rate)建议在数组扁平化或组装响应前,就用
number_format或sprintf固化格式


















