1、IEEE 754 雙精確度浮點(diǎn)數(shù)(Double 64 Bits)中尾數(shù)部分是用來(lái)存儲(chǔ)整數(shù)的有效位數(shù),為 52 位,加上省略的一位 1 可以保存的實(shí)際數(shù)值為
Math.pow(2, 53) // 9007199254740992
Number.MAX_SAFE_INTEGER // 最大安全整數(shù) 9007199254740991
Number.MIN_SAFE_INTEGER // 最小安全整數(shù) -9007199254740991
2、實(shí)際存儲(chǔ)時(shí) 如果超過(guò) 最值,會(huì)發(fā)生轉(zhuǎn)化
const num = 200000436035958034;
console.log(num); // 200000436035958050
還有常見的場(chǎng)景是 經(jīng)過(guò)JSON.parse 序列化后 大數(shù)超過(guò)最值, 也會(huì)被轉(zhuǎn)化; 原因是 JSON 的schema 是 object, array, number, or string , 所以對(duì)數(shù)字自動(dòng)轉(zhuǎn)化
3、處理方式
- 轉(zhuǎn)為字符串: 最為常見
- BigInt
// 方法1
200000436035958034n; // 200000436035958034n
// 方法2
BigInt('200000436035958034') // 200000436035958034n
// 注意要使用字符串否則還是會(huì)被轉(zhuǎn)義
BigInt(200000436035958034) // 200000436035958048n 這不是一個(gè)正確的結(jié)果
但BigInt 類型 不能直接進(jìn)行JOSN.parse , 會(huì)報(bào)錯(cuò),因?yàn)椴环螶SON的schema
- 第三方庫(kù): json-bigint
不要直接使用 JSON.parse() ,在接收數(shù)據(jù)流之后,先通過(guò)字符串方式進(jìn)行解析,利用 json-bigint 這個(gè)庫(kù),會(huì)自動(dòng)的將超過(guò) 2 的 53 次方類型的數(shù)值轉(zhuǎn)為一個(gè) BigInt 類型,再設(shè)置一個(gè)參數(shù) storeAsString: true 會(huì)將 BigInt 自動(dòng)轉(zhuǎn)為字符串。
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 {
// 使用第三方庫(kù)進(jìn)行 JSON 序列化
const obj = JSONbig.parse(data)
console.log('經(jīng)過(guò) 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);
});
總結(jié)自Node.js 中遇到大數(shù)處理精度丟失如何解決?前端也適用!
hi~ 今天的你開心不~~