1鲜戒、IEEE 754 雙精確度浮點數(shù)(Double 64 Bits)中尾數(shù)部分是用來存儲整數(shù)的有效位數(shù),為 52 位,加上省略的一位 1 可以保存的實際數(shù)值為
Math.pow(2, 53) // 9007199254740992
Number.MAX_SAFE_INTEGER // 最大安全整數(shù) 9007199254740991
Number.MIN_SAFE_INTEGER // 最小安全整數(shù) -9007199254740991
2、實際存儲時 如果超過 最值竣灌,會發(fā)生轉化
const num = 200000436035958034;
console.log(num); // 200000436035958050
還有常見的場景是 經(jīng)過JSON.parse 序列化后 大數(shù)超過最值, 也會被轉化秆麸; 原因是 JSON 的schema 是 object, array, number, or string 初嘹, 所以對數(shù)字自動轉化
3、處理方式
- 轉為字符串: 最為常見
- BigInt
// 方法1
200000436035958034n; // 200000436035958034n
// 方法2
BigInt('200000436035958034') // 200000436035958034n
// 注意要使用字符串否則還是會被轉義
BigInt(200000436035958034) // 200000436035958048n 這不是一個正確的結果
但BigInt 類型 不能直接進行JOSN.parse 沮趣, 會報錯屯烦,因為不符合JSON的schema
- 第三方庫: json-bigint
不要直接使用 JSON.parse() ,在接收數(shù)據(jù)流之后房铭,先通過字符串方式進行解析驻龟,利用 json-bigint 這個庫,會自動的將超過 2 的 53 次方類型的數(shù)值轉為一個 BigInt 類型缸匪,再設置一個參數(shù) storeAsString: true 會將 BigInt 自動轉為字符串迅脐。
node端使用:
const http = require('http');
const JSONbig = require('json-bigint')({ 'storeAsString': true});
http.createServer((req, res) => {
if (req.method === 'POST') {
let data = '';
req.on('data', chunk => {
data += chunk;
});
req.on('end', () => {
try {
// 使用第三方庫進行 JSON 序列化
const obj = JSONbig.parse(data)
console.log('經(jīng)過 JSON 反序列化之后:', obj);
res.setHeader("Content-Type", "application/json");
res.end(data);
} catch(e) {
console.error(e);
res.statusCode = 400;
res.end("Invalid JSON");
}
});
} else {
res.end('OK');
}
}).listen(3000)
axios中使用:
const axios = require('axios').default;
const JSONbig = require('json-bigint')({ 'storeAsString': true});
const request = axios.create({
baseURL: 'http://localhost:3000',
transformResponse: [function (data) {
return JSONbig.parse(data)
}],
});
request({
url: '/api/test'
}).then(response => {
// 200000436035958034
console.log(response.data.num);
});
總結自Node.js 中遇到大數(shù)處理精度丟失如何解決?前端也適用豪嗽!
hi~ 今天的你開心不~~