【问题标题】:JavaScript summing large integersJavaScript 对大整数求和
【发布时间】:2011-06-01 05:55:04
【问题描述】:

在 JavaScript 中,我想使用以下方法创建大型布尔数组(54 个元素)的二进制哈希:

function bhash(arr) {
   for (var i = 0, L = arr.length, sum = 0; i < L; sum += Math.pow(2,i)*arr[i++]); 
   return sum;
}

简而言之:它创建了存储布尔数组的最小整数。现在我的问题是 javascript 显然使用 floats 作为默认值。我必须创建的最大数字是 2^54-1 但是一旦 javascript 达到 2^53 它就会开始做奇怪的事情:

9007199254740992+1 = 9007199254740994

有没有办法在javascript中使用整数而不是浮点数?还是大整数求和?

【问题讨论】:

  • Javascript 不仅默认使用浮点类型,它还没有 任何其他数字类型 - 显然不是该语言的“好部分”。跨度>

标签: javascript biginteger


【解决方案1】:

您可以通过谷歌搜索找到各种 BigInteger Javascript 库。例如http://www.leemon.com/crypto/BigInt.html

【讨论】:

  • 我执行了以下操作:&lt;SCRIPT LANGUAGE="JavaScript" SRC="BigInt.js"&gt;&lt;/SCRIPT&gt; 但 cosole 给了我一个错误 > 数组长度无效:“buff=new Array(k);”
【解决方案2】:

没有。 Javascript 只有一种数字类型。您必须自己编写代码或使用大型整数库(甚至不能重载算术运算符)。

更新

这在 2010 年是真的……现在(2019 年)BigInt 库正在标准化,很可能很快就会在 Javascript 中以原生方式出现,它将是第二个存在的数字类型(有类型化数组,但是 - 至少在形式上- 从它们中提取的值仍然是双精度浮点数)。

【讨论】:

    【解决方案3】:

    JavaScript 内部使用浮点数。

    What is JavaScript's highest integer value that a number can go to without losing precision?

    换句话说,您不能使用超过 53 位。在某些实现中,您可能会被限制为 31 个。

    尝试将位存储在多个变量中,使用字符串,或获取bignum library,或者如果您只需要处理整数,则使用biginteger library

    【讨论】:

    【解决方案4】:

    您的系统可能遇到了字节长度限制。我将获取布尔数组,将其转换为二进制数字数组([true, false, true] => [1,0,1]),然后将此数组加入字符串“101”,然后使用 parseInt ('101',2),你就会得到答案。

    【讨论】:

      【解决方案5】:

      这里是(yet another) wrapper around Leemon Baird's BigInt.js

      online demo of a big integer calculator in JavaScript 中使用了它,它实现了通常的四个操作 + - * /、模数 (%) 和四个内置函数:平方根 (sqrt)、幂 (pow)、递归阶乘 ( fact) 和一个记忆斐波那契 (fibo)。

      【讨论】:

        【解决方案6】:

        www.javascripter.net/math/calculators/100digitbigintcalculator.htm 提供了大整数运算的另一种实现(也使用 BigInt.js)。支持操作 + - * / 以及余数、GCD、LCM、阶乘、素数测试、下一个素数、上一个素数。

        【讨论】:

          【解决方案7】:

          javascript 现在有experimental support for BigInt
          在撰写本文时,只有 chrome 支持这一点。

          caniuse还没有条目。

          BigInt 可以与构造函数一起使用,例如BigInt(20) 或附加 n,例如20n

          例子:

          const max = Number.MAX_SAFE_INTEGER;
          
          console.log('javascript Number limit reached', max + 1 === max + 2) // true;
          
          console.log('javascript BigInt limit reached', BigInt(max) + 1n === BigInt(max) + 2n); // false

          【讨论】:

            【解决方案8】:

            BigInt 被添加为 JavaScript 的原生功能。

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

            例子:

            const max = BigInt(Number.MAX_SAFE_INTEGER);
            const two = 2n;
            const result = max + two;
            console.log(result);
            // → '9007199254740993'
            

            【讨论】:

            • 谢谢。 “n”代表什么?
            • 可以添加 n 后缀来明确告诉解释器将整数视为 BigInt 而不是数字,而不是将 BigInt() 作为函数调用。
            【解决方案9】:

            因此,在尝试其中一个 leetcode 问题时,我编写了一个函数,它以字符串的形式接收两个数字,并以字符串的形式返回这些数字的总和。 (这不适用于负数,尽管我们可以修改此函数以覆盖它)

            var addTwoStr = function (s1, s2) {
            s1 = s1.split("").reverse().join("")
            s2 = s2.split("").reverse().join("")
            var carry = 0, rS = '', x = null
            if (s1.length > s2.length) {
                for (let i = 0; i < s1.length; i++) {
                    let s = s1[i]
                    if (i < s2.length) {
                        x = Number(s) + Number(s2[i]) + carry
                        rS += String((x % 10))
                        carry = parseInt(x/10)
                    } else {
                        if (carry) {
                            x = Number(s) + carry
                            rS += String((x % 10))
                            carry = parseInt(x/10)
                        } else {
                            rS += s
                        }
                    }
                }
            } else {
                for (let i = 0; i < s2.length; i++) {
                    let s = s2[i]
                    if (i < s1.length) {
                        x = Number(s) + Number(s1[i]) + carry
                        rS += String((x % 10))
                        carry = parseInt(x/10)
                    } else {
                        if (carry) {
                            x = Number(s) + carry
                            rS += String((x % 10))
                            carry = parseInt(x/10)
                        } else {
                            rS += s
                        }
                    }
                }
            }
            if (carry) {
                rS += String(carry)
            }
            return rS.split("").reverse().join("")
            }
            

            示例:addTwoStr('120354566', '321442535') 输出:“441797101”

            【讨论】:

              【解决方案10】:
              /** --if you want to show a big int as your wish use install and require this module
               * By using 'big-integer' module is easier to use and handling the big int numbers than regular javascript
               * https://www.npmjs.com/package/big-integer
              */
              
              let bigInt = require('big-integer');
              
              //variable: get_bigInt
              let get_bigInt = bigInt("999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999");
              
              let arr = [1, 100000, 21, 30, 4, BigInt(999999999999), get_bigInt.value];
              
              console.log(arr[6]); // Output: 999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999n
              
              //Calculation
              console.log(arr[6] + 1n); // +1
              console.log(arr[6] + 100n); // +100
              console.log(arr[6] - 1n); // -1
              console.log(arr[6] - 10245n); // -1000n
              
              console.log((arr[6] * 10000n) + 145n - 435n);
              
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2016-02-13
                • 1970-01-01
                • 1970-01-01
                • 2019-07-08
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多