JavaScript对JSON数组排序时数值被四舍五入如何保留原始值?
首先明确:你使用的排序逻辑本身不会修改数组内元素的数值,精度丢失在JSON接口返回值被解析为JS对象的阶段就已经发生了。
根本原因
JS的Number类型遵循IEEE 754双精度浮点数标准,最多只能精确表示15-17位十进制有效数字,你给出的原始数值1.1103391379964032864981076624有效位数远超这个上限,只要被解析为Number类型就会自动截断舍入,和后续的排序操作没有关联。
解决方案
方案1(最稳妥,推荐):调整接口返回格式
要求接口侧输出JSON时,将需要保留高精度的浮点值改为字符串类型,用双引号包裹。JS解析后会直接保留原始字符串形式,排序、存储都不会丢失精度,需要做运算时再按需转换即可。
方案2:自定义JSON解析逻辑
如果无法修改接口返回规则,可以放弃默认的JSON.parse解析逻辑,对接口返回的原始JSON字符串做预处理:
- 用正则匹配出所有超长精度的数值,将其替换为字符串形式
- 再用
JSON.parse解析,即可得到原始数值的字符串形式
示例代码:
// 原始接口返回的JSON字符串 const rawResponse = '[{"Id":2,"highPrecisionNum":1.1103391379964032864981076624},{"Id":1,"highPrecisionNum":2.2203391379964032864981076624}]' // 预处理:把超长数字匹配出来转成字符串形式 const processedStr = rawResponse.replace(/:\s*(\d\.\d{17,})/g, ':"$1"') // 解析后即可得到原始字符串形式的高精度数值 const data = JSON.parse(processedStr) // 后续排序逻辑不受影响 data.sort(function(a, b) { return (a.Id - b.Id) })
方案3:使用高精度运算库
如果后续需要对该数值做加减乘除等运算,可以引入Decimal.js等高精度运算库,将数值存储为库提供的专用类型,全程避免使用原生Number类型,防止精度丢失。
内容的提问来源于stack exchange,提问作者benevolent
相关产品推荐
相关产品推荐

