web-dev-qa-db-ja.com

大きな整数を合計するJavaScript

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で浮動小数点数の代わりに整数を使用する方法はありますか?または大きな整数の合計?

23
Raven

JavaScriptは内部的に浮動小数点を使用します。

数値が精度を失うことなく移動できるJavaScriptの最大整数値は何ですか?

つまり、53ビットを超えて使用することはできません。一部の実装では、31に制限される場合があります。

ビットを複数の変数に格納するか、文字列を使用するか、または bignumライブラリ を取得するか、整数のみを処理する必要がある場合は bigintegerライブラリ を取得してください。

18
martona

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
5
Razor

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'
4
Mahmoud Khaled

いいえ。JavaScriptには数値タイプが1つしかありません。自分でコーディングするか、大きな整数ライブラリを使用する必要があります(算術演算子をオーバーロードすることもできません)。

更新

これは2010年にも当てはまります...現在(2019)BigIntライブラリは標準化されており、おそらくすぐにJavascriptでネイティブに到着し、2番目の数値型になります(型付き配列がありますが、少なくとも正式には-値が抽出されます)それらからまだ倍精度浮動小数点数です)。

3
6502

大整数演算の別の実装(BigInt.jsも使用)は www.javascripter.net/math/calculators/100digitbigintcalculator.htm で入手できます。演算+-* /のほか、残り、GCD、LCM、階乗、素数検定、次の素数、前の素数をサポートします。

1
Alex K

システムでバイト長の制限に達している可能性があります。ブール値の配列を取り、それを2進数の配列([true、false、true] => [1,0,1])に変換し、この配列を文字列 "101"に結合してから、parseIntを使用します( '101'、2)、そしてあなたはあなたの答えを持っているでしょう。

0
Stephen C

したがって、リートコードの問題の1つを試行しているときに、2つの数値を文字列の形式で受け取り、それらの数値の合計を文字列の形式で返す関数を作成しました。 (これをカバーするようにこの関数を変更することはできますが、これは負の数では機能しません)

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"

0
Abhishek Verma

これが (まだ別の)レモンベアードのBigInt.jsのラッパーです

これは JavaScriptでの大整数計算機のオンラインデモ で使用され、通常の4つの演算+-* /、係数(%)、および4つの組み込み関数(平方根(sqrt)、力(捕虜)、再帰的な階乗(事実)、記憶するフィボナッチ(フィボ)。

0
YSharp

グーグルで見つけることができるさまざまなBigInteger Javascriptライブラリがあります。例えば http://www.leemon.com/crypto/BigInt.html

0
z5h