直接用json.loads()解析高精度数字必丢精度,因float受限于ieee 754双精度(仅15–17位有效数字);须用parse_float=decimal.decimal或字符串暂存以保精度。

直接用 json.loads() 解析含高精度数字的 JSON 字符串,一定会丢精度——这不是 bug,是 float 类型的底层限制。必须绕过 float,改用 decimal.Decimal 或字符串暂存。
Python json.loads() 为什么默认丢精度
JSON 字符串里的数字(如 "1234567890123456789.0123456789")在 json.loads() 中默认转成 Python 的 float,而 float 是 IEEE 754 双精度,最多精确到 15–17 位十进制数字。超出部分会被舍入或转科学计数法。
- 小数:
"3.14159265358979323846"→3.141592653589793(末尾 10 位消失) - 大整数:
"1234567890123456789"→1234567890123456800(末几位被“抹平”) - 即使值是
10.00000,也会变成10.0,末尾零全丢
用 parse_float=decimal.Decimal 保留原始小数精度
这是最轻量、最直接的修复方式,不改数据结构,只换解析时的类型转换逻辑。
- 必须导入
decimal模块 -
parse_float参数只影响 JSON 中的 number 字段,不影响字符串、布尔、null - 返回的是
Decimal实例,后续需显式调用str()或to_eng_string()输出原始字符串形式 - 不能直接用于 numpy/scipy 等依赖
float的库,得先转float(此时又丢精度)或保持Decimal运算
示例:
import json
import decimal
<p>s = '{"price": 129.99000, "pi": 3.1415926535897932384626433832795}'
data = json.loads(s, parse_float=decimal.Decimal)</p><h1>{'price': Decimal('129.99000'), 'pi': Decimal('3.1415926535897932384626433832795')}</h1>
大整数(>2^53)必须走字符串路径
decimal.Decimal 能保小数精度,但对超长整数(比如 19 位订单 ID)仍可能因构造时隐式转 float 出问题。更稳妥的方式是:让 JSON 字符串里数字本身带引号,即传字符串而非数字。
- 后端应在序列化前就把
long/int字段转成str,例如:data["id"] = str(order_id) - 前端 JavaScript 才不会在
JSON.parse()时把它当 number 处理 - Python 端收到的就是
str,可按需用int()或decimal.Decimal()构造,完全可控 - 如果无法改后端,只能预处理 JSON 字符串:用正则把疑似大整数的裸数字包上引号,再
json.loads()
正则预处理示例(慎用,需结合业务字段名):
import re
import json
<p>raw = '{"id": 1234567890123456789, "amount": 99.99}'
safe = re.sub(r':\s*(\d{17,})', r': "\1"', raw) # 匹配17位以上裸整数
data = json.loads(safe) # {'id': '1234567890123456789', 'amount': 99.99}</p>
Decimal 和字符串方案的关键区别
选 decimal.Decimal 还是字符串,取决于你后续怎么用这个值:
- 要做加减乘除、金融计算?用
decimal.Decimal,它支持精确十进制运算 - 只是展示、透传、拼接 URL 或 DB 查询条件?字符串更安全、更省事、无类型转换风险
- 要喂给 pandas / sklearn / requests 等库?查清它们是否接受
Decimal;否则字符串 + 显式float()或int()更稳 - 字段含义模糊(比如既可能是 ID 又可能是金额)?统一字符串,由业务层决定怎么 cast
真正容易被忽略的不是“怎么修”,而是“修完之后怎么用”。Decimal 不等于 float,也不等于 str,它是个独立类型——一旦用了 parse_float=decimal.Decimal,所有下游代码都得适配它,否则 runtime error 或静默精度丢失会卷土重来。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










