【问题标题】:Is there a library similar to Math that supports JavaScript BigInt?是否有类似 Math 的库支持 JavaScript BigInt?
【发布时间】:2019-01-22 20:04:45
【问题描述】:

我正在尝试使用数学库的一些功能,例如(pow、floor 等)。但是,当我尝试将它们与这样的 Big Int 一起使用时......

let x = Math.pow(100n, 100n);

我明白了

TypeError:无法将 BigInt 值转换为数字

当然我可以自己实现,比如...

const BigMath ={
  pow(num, pow){
    let total;
    for(let i = 0; i < pow; i++){
      if(!total) total = num;
      else total = total * num;
    }
    return total;
  }
} 
let x = BigMath.pow(100n, 100n);

但我不想返回并重新实现所有功能。特别是因为从我的实现看来,它应该能够处理它没有问题。

那么如何使用 BigInt 处理 Math.*?

【问题讨论】:

    标签: javascript bigint


    【解决方案1】:

    对于pow(),您可以简单地使用** 运算符:

    Math.pow(2, 175)
    // 4.789048565205903e+52
    2**175
    // 4.789048565205903e+52
    2n**175n
    // 47890485652059026823698344598447161988085597568237568n
    

    floor() 像大多数 Math 函数一样与整数无关。

    事实上,只有 5 个Math 函数与整数相得益彰:

    • Math.abs()
    • Math.max()
    • Math.min()
    • Math.pow()
    • Math.sign()

    其他函数涉及实数:

    • 三角函数(cosacossinasintanatanatan2
    • 双曲线函数(coshacoshsinhasinhtanhatanh
    • 根(sqrtcbrthypot
    • 圆形(roundceilfloortrunc
    • 对数(expexpm1loglog10log1plog2
    • 随机 (random)
    • 位(clz32froundimul

    所以,这里相当于MathBigInt

    const bigMath = {
      abs(x) {
        return x < 0n ? -x : x
      },
      sign(x) {
        if (x === 0n) return 0n
        return x < 0n ? -1n : 1n
      },
      pow(base, exponent) {
        return base ** exponent
      },
      min(value, ...values) {
        for (const v of values)
          if (v < value) value = v
        return value
      },
      max(value, ...values) {
        for (const v of values)
          if (v > value) value = v
        return value
      },
    }
    

    【讨论】:

      【解决方案2】:

      BigInts 以它自己的方式是一种不同的数据类型,你不能比较不要在表达式中使用它们

      typeof 123;  // 'number'
      typeof 123n; // 'bigint'
      

      数字不能表示超出安全整数限制的 BigInts,这就是为什么不允许在 BigInts 和 Numbers 之间混合操作(比较运算符 ===、 除外),因为任何隐式转换都可能丢失信息

      所以你可以做的是添加一个隐式转换

      Number( Math.pow( Number(100n) , Number(100n) ) ); // 1.0000000000000005e+200
      

      【讨论】:

      • 转成数字的时候不会这一轮吗?
      • 是的,如果这是你的观点,那么 JavaScript 中没有内置的 pow BigInts 方法,那么已经存在一个允许它的 BigInt liberary
      • 这会丢失精度,请改用** 运算符
      【解决方案3】:

      您可以使用Basenumber.js,它允许 BigIntBigDecimal 操作:

      电源

      let x = Base('100');
      let y = Base('100');
      
      let z = x.pow(y);
      
      console.log( z.toString() );
      console.log( z.toExponential(1) );
      &lt;script src='https://cdn.jsdelivr.net/gh/AlexSp3/Basenumber.js@main/BaseNumber.min.js'&gt;&lt;/script&gt;

      部门

      let x = Base('1e+10000');
      let y = Base('999999999999999999999999999999999');
      
      let z = x.divide(y);
      
      console.log(z.toString());
      console.log(z.toExponential(1));
      &lt;script src='https://cdn.jsdelivr.net/gh/AlexSp3/Basenumber.js@main/BaseNumber.min.js'&gt;&lt;/script&gt;

      【讨论】:

        猜你喜欢
        • 2019-12-15
        • 1970-01-01
        • 2020-12-25
        • 2011-12-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多