簡體   English   中英

JavaScript 對大整數求和

[英]JavaScript summing large integers

在 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 顯然使用浮點數作為默認值。 我必須創建的最大數字是 2^54-1,但是一旦 javascript 達到 2^53,它就會開始做奇怪的事情:

9007199254740992+1 = 9007199254740994

有沒有辦法在javascript中使用整數而不是浮點數? 還是大整數求和?

JavaScript 在內部使用浮點數。

一個數字在不損失精度的情況下可以達到的 JavaScript 的最高整數值是多少?

換句話說,您不能使用超過 53 位。 在某些實現中,您可能被限制為 31。

嘗試將位存儲在多個變量中,使用字符串或獲取bignum 庫,或者如果您只需要處理整數,則使用biginteger 庫

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'

javascript 現在有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

不可以。Javascript 只有一種數字類型。 您必須自己編寫代碼或使用大型整數庫(您甚至不能重載算術運算符)。

更新

這在 2010 年是正確的......現在(2019 年)一個 BigInt 庫正在被標准化,並且很可能很快就會在 Javascript 中原生出現,它將成為第二個數字類型(有類型化數組,但 - 至少正式 - 提取的值從他們那里仍然是雙精度浮點數)。

大整數算法的另一種實現(也使用 BigInt.js)可在www.javascripter.net/math/calculators/100digitbigintcalculator.htm 獲得 支持運算 + - * / 以及余數、GCD、LCM、階乘、素性檢驗、下一個素數、前一個素數。

這是Leemon Baird 的 BigInt.js(又一個)包裝器

它用於JavaScript 中的大型整數計算器的在線演示,它實現了通常的四個運算 + - * /、模數 (%) 和四個內置函數:平方根 (sqrt)、冪 (pow)、遞歸階乘(事實)和記憶斐波那契數列(fibo)。

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

您可能會遇到系統上的字節長度限制。 我取布爾數組,將其轉換為二進制數字數組 ([true, false, true] => [1,0,1]),然后將此數組加入字符串“101”,然后使用 parseInt ('101',2),你就會得到答案。

因此,在嘗試其中一個 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”

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM