当JS处理大整数或者浮点数的时候会出现精度丢失的情况。
Javascript的数字都使用双精度浮点数表示,遵循IEEE754标准
比如我遇到的问题,对一个小数的四舍五入,保留2位小数:
235.985≈235.98
235.9851≈235.99
原理请大家参考百度,本文只提供解决方案:
在JavaScript中处理精度丢失问题,可以采用以下方法:
1. 大整数处理
- 使用字符串传输:与后端约定,将大整数(如ID)作为字符串返回,避免JSON解析时转为不准确的Number。
- JSON解析处理:使用
JSON.parse
的reviver函数检测并转换大数为字符串:JSON.parse(jsonString, (key, value) => {if (typeof value === 'number' && (value > Number.MAX_SAFE_INTEGER || value < Number.MIN_SAFE_INTEGER)) {return value.toString(); // 转换为字符串}return value; });
- 使用BigInt类型:对需要运算的大整数,使用ES6的
BigInt
:const bigNum = BigInt("12345678901234567890"); // 使用字符串初始化 console.log(bigNum + 1n); // 运算需使用同类型
2. 浮点数精度问题
- 转为整数计算:
const result = (0.1 * 10 + 0.2 * 10) / 10; // 0.3
- 使用第三方库(如
decimal.js
):import Decimal from 'decimal.js'; const sum = new Decimal(0.1).plus(0.2).toString(); // "0.3"
3. 第三方库推荐
- 大数运算:
bignumber.js
、math.js
- 精确小数:
decimal.js
、big.js
4. JSON序列化BigInt
- 自定义序列化方法:
const data = { id: 12345678901234567890n }; const json = JSON.stringify(data, (key, value) => typeof value === 'bigint' ? value.toString() : value );
5. 前后端协作
- 明确数据格式:确保可能超出安全范围的字段(如ID、长整型)以字符串形式传输。
总结
- 大整数:优先字符串传输,使用
BigInt
或库处理。 - 浮点数:转为整数计算或使用专用库。
- 兼容性:检查
BigInt
支持情况,必要时引入Polyfill。
通过以上策略,可有效避免JavaScript中的精度丢失问题。