js 字符串转整数 然后在+百万的数 为什么计算结果会出错?

3825567180763585000 + 100万 200万 300万的时候计算结果都是正常的 为什么
+400万的时候 计算结果就出错了3825567180767585300
image.png
怎么保证计算正确性 谢谢

阅读 845
4 个回答

超出最大整数就会出现不正常的结果,首先了解下BigInt,就是为了解决这个问题

BigInt数据类型的目的是比Number数据类型支持的范围更大的整数值.在对大整数执行数学运算时,以任意精度表示整数的能力尤为重要,使用BigInt,整数溢出将不再是问题.

最大整数: Number.MAX_SAFE_INTEGER -> 9007199254740991

最小整数: Number.MIN_SAFE_INTEGER -> -9007199254740991

创建:BigInt("9007199254740995"); // → 9007199254740995n

//不使用BigInt返回结果是异常的
9007199254740992 === 9007199254740993   true

//使用BigInt返回结果是正常的
9007199254740992n === 9007199254740993n  false


BigInt("9007199254740995") + BigInt("9007199254740995")=18014398509481990n

Number(18014398509481990n) = 18014398509481990

了解下关于安全整数的概念

保证不出错的办法

  • 使用bignumber这个库: https://www.npmjs.com/package/bignumber.js

    /**
     * JavaScript中的加减乘除的精度的问题
     * 基于bignumber.js
     */
     
    const BigNumber = require('bignumber.js')
    class MyBigNumber {
    /**
     * 加法 用例: 0.1 + 0.2 ?= 0.3
     */
    static plus(a, b) {
      const r = new BigNumber(a).plus(b)
     
      // @Test Logger
      console.log(`【加法】-处理前:${a + b}, 处理后:${r}`)
     
      return +r.toString()
    }
     
    /**
     * 减法 用例:0.12 - 0.1 ?= 0.02
     */
    static minus(a, b) {
      const r = new BigNumber(a).minus(b)
     
      // @Test Logger
      console.log(`【减法】-处理前:${a - b}, 处理后:${r}`)
     
      return +r.toString()
    }
     
    /**
     * 乘法 用例:1.15 * 100 ?= 115
     */
    static mul(a, b) {
      const r = new BigNumber(a).multipliedBy(b)
     
      // @Test Logger
      console.log(`【乘法】-处理前:${a * b}, 处理后:${r}`)
     
      return +r.toString()
    }
     
    /**
     * 除法 用例: 0.15 / 0.1 ?= 1.5
     */
    static div(a, b) {
      const r = new BigNumber(a).dividedBy(b)
     
      // @Test Logger
      console.log(`【除法】-处理前:${a / b}, 处理后:${r} `)
     
      return +r.toString()
    }
    }

BigInt

console.log(3825567180763585000n + 4000000n)
// 3825567180767585000n

3825567180763585000 已经超出了 number 类型最大的安全整数(2^53-1)

Number.isSafeInteger(3825567180763585000) 
// log => false

所以改用成 BigInt 就可以了。或者使用一些第三方的大数运算库,比如说 big.js 来处理大数运算。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏