简体   繁体   English

是否有类似于 Math 的库支持 JavaScript BigInt?

[英]Is there a library similar to Math that supports JavaScript BigInt?

I am trying to use some functions of the Math library such as (pow, floor, etc).我正在尝试使用数学库的一些函数,例如(pow、floor 等)。 However, when I try to use them with a Big Int like this...但是,当我尝试将它们与这样的 Big Int 一起使用时......

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

I get我得到

TypeError: Cannot convert a BigInt value to a number类型错误:无法将 BigInt 值转换为数字

of course I can implement this myself, something like...当然我可以自己实现这个,比如......

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);

But I don't want to have to go back through and reimplement all of the functions.但我不想返回并重新实现所有功能。 Especially since it seems like from my implementation it should be able to handle it no problem.特别是因为从我的实现来看,它应该能够处理它没有问题。

So how do I handle Math.* with a BigInt?那么我如何使用 BigInt 处理 Math.* 呢?

For pow() you can simply use ** operator:对于pow()您可以简单地使用**运算符:

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

floor() like most Math functions is not relevant with integers. floor()像大多数Math函数一样与整数无关。

In fact, only 5 Math functions seam to be revelent with integers:事实上,只有 5 个Math函数与整数有关:

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

The other functions concern real numbers:其他函数涉及实数:

  • Trigonometric functions ( cos , acos , sin , asin , tan , atan , atan2 )三角函数( cosacossinasintanatanatan2
  • Hyperbolic functions ( cosh , acosh , sinh , asinh , tanh , atanh )双曲函数( coshacoshsinhasinhtanhatanh
  • Roots ( sqrt , cbrt , hypot )罗茨( sqrtcbrthypot
  • Round ( round , ceil , floor , trunc )圆形( roundceilfloortrunc
  • Logarithm ( exp , expm1 , log , log10 , log1p , log2 )对数( expexpm1loglog10log1plog2
  • Random ( random )随机( random
  • Bit ( clz32 , fround , imul )位( clz32froundimul

So, here is the equivalent of Math for BigInt :所以,这里是BigIntMath等价物:

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
  },
}

BigInts is a different datatype in its own way you can't have compare not use them as such in an expression BigInts 以自己的方式是一种不同的数据类型,您不能在表达式中进行比较而不是这样使用它们

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

Numbers can't represent BigInts beyond the safe integer limit that's why it's not allowed to mix operations between BigInts and Numbers (except for comparison operators ===,<,>) as any implicit conversion could lose information数字不能表示超出安全整数限制的 BigInt,这就是为什么不允许在 BigInt 和数字之间混合操作(比较运算符 ===、<、> 除外),因为任何隐式转换都可能丢失信息

So what you can do is add an implicit casting所以你可以做的是添加一个隐式转换

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

You can use Basenumber.js which allows BigInt and BigDecimal operations:您可以使用Basenumber.js ,它允许BigIntBigDecimal操作:

Power力量

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

Division分配

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM