美文网首页现代前端指南!
Javascript中大数处理

Javascript中大数处理

作者: 捡了幸福的猪 | 来源:发表于2021-08-18 22:16 被阅读0次

    1、IEEE 754 双精确度浮点数(Double 64 Bits)中尾数部分是用来存储整数的有效位数,为 52 位,加上省略的一位 1 可以保存的实际数值为

    Math.pow(2, 53) // 9007199254740992
    
    Number.MAX_SAFE_INTEGER // 最大安全整数 9007199254740991 
    Number.MIN_SAFE_INTEGER // 最小安全整数 -9007199254740991
    

    2、实际存储时 如果超过 最值,会发生转化

    const num = 200000436035958034;
    console.log(num); // 200000436035958050
    

    还有常见的场景是 经过JSON.parse 序列化后 大数超过最值, 也会被转化; 原因是 JSON 的schema 是 object, array, number, or string , 所以对数字自动转化

    3、处理方式

    • 转为字符串: 最为常见
    • BigInt
    // 方法1
    200000436035958034n; // 200000436035958034n
    // 方法2
    BigInt('200000436035958034') // 200000436035958034n
    
    // 注意要使用字符串否则还是会被转义
    BigInt(200000436035958034) // 200000436035958048n 这不是一个正确的结果
    

    但BigInt 类型 不能直接进行JOSN.parse , 会报错,因为不符合JSON的schema

    • 第三方库: json-bigint
      不要直接使用 JSON.parse() ,在接收数据流之后,先通过字符串方式进行解析,利用 json-bigint 这个库,会自动的将超过 2 的 53 次方类型的数值转为一个 BigInt 类型,再设置一个参数 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('经过 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 中遇到大数处理精度丢失如何解决?前端也适用!

    hi~ 今天的你开心不~~

    相关文章

      网友评论

        本文标题:Javascript中大数处理

        本文链接:https://www.haomeiwen.com/subject/bepnbltx.html