BigInt
はJavaScriptの新しい数値プリミティブデータ型であり、任意の精度の数値を操作できます。 BigInt
すると、 Number
最大安全整数値を超えても、大きな整数を安全に格納および処理できます。 この記事では、 BigInt
とChrome 67の新機能の使用例をいくつか見て、JavaScriptでBigInt
とNumber
を比較します。
使用例
任意の精度の整数は、JavaScriptの多くの新しい用途を開きます。
BigIntは、数学演算でのオーバーフローエラーの防止に役立ちます。 この事実はそれ自体で無数の可能性を利用可能にします。たとえば、金融テクノロジーでは一般に、多数の数学的操作が使用されます。
JavaScriptのNumber
データ型では、 大きな数値識別子と高精度のタイムスタンプを安全に表すことができません。 これは多くの場合 エラーにつながり、開発者はそれらを文字列として保存する必要があります。 BigInt
このデータは数値として表現できます。
BigInt
は、 BigDecimal
データ型の可能な実装で使用できます。 これにより、操作中に精度を損なうことなく(たとえば、問題なく0.10 + 0.20 !== 0.30
)、小数値の形で金額を格納できます。
これらのケースのいずれかのJavaScriptの以前では、 BigInt
機能をエミュレートするライブラリを使用する必要がありました。 BigInt
が広く利用可能になると、ネイティブにサポートされているBigInt
優先して、これらの依存関係を放棄することが可能になります。 これにより、実行時間のパフォーマンスが向上するだけでなく、負荷、解析、およびコンパイル時間が短縮されます。
ネイティブBigInt
は一般的なカスタムライブラリよりも高速です
BigInt
は、新しい構文をライブラリAPI呼び出しに変換するために、必要な機能を実装するライブラリと、変換ステップが必要です。 Babelは現在、 BigInt
リテラルの解析をサポートしていますが、変換できません。 したがって、 BigInt
がさまざまなブラウザーとの互換性を必要とするサイトのBigInt
で使用されることを期待していません。 ただし、この機能がブラウザーに表示されるようになったので、BigIntの実験を開始して、BigIntのサポートが徐々に増えることを期待できます。
現状:番号
プリミティブJavaScriptデータ型Number
は、倍精度浮動小数点Number
で表されます。 定数Number.MAX_SAFE_INTEGER
は、1だけ安全に増やすことができる最大の整数が含まれています。 その値は2 ** 53-1
です。
const max = Number.MAX_SAFE_INTEGER; // → 9_007_199_254_740_991
注:読みやすくするために、アンダースコアを区切り文字として使用して番号をグループ化します。 適切な文により、通常のJavaScript数値リテラルにこのような表記を使用できます。
1つずつ増やすと、期待される結果が得られます。
max + 1; // → 9_007_199_254_740_992
しかし、もう1つ増やした場合、 Number
は結果を正確に保存できません。
max + 2; // → 9_007_199_254_740_992
式max + 1
の結果は、式max + 2
結果と等しくなることに注意してください。 したがって、JavaScriptでこの特定の値を取得するたびに、それが正確であるかどうかを言うことはできません。 安全な整数範囲外(つまり、 Number.MIN_SAFE_INTEGER
からNumber.MIN_SAFE_INTEGER
まで)の整数を使用した計算は、潜在的にNumber.MAX_SAFE_INTEGER
です。 このため、安全な範囲の整数値のみに依存できます。
新規:BigInt
BigInt
はJavaScriptの新しい数値プリミティブデータ型であり、任意の精度の数値を操作できます。 BigInt
すると、 Number
最大安全整数値を超えても、大きな整数を安全に格納および処理できます。
BigInt
を作成するには、整数のリテラル表記に接尾辞n
を追加するだけです。 たとえば、 123
は123n
なり123n
。 グローバル関数BigInt(number)
を使用して、数値をBigInt
にキャストできます。 つまり、 BigInt(123) === 123n
です。 これを使用して、上で説明した問題を解決しましょう。
BigInt(Number.MAX_SAFE_INTEGER) + 2n; // → 9_007_199_254_740_993n
以下に、 Number
型の2つの数値を乗算する別の例を示します。
1234567890123456789 * 123; // → 151851850485185200000
下位桁の9
と3
を見ると、乗算の結果は7
終わるはずだと主張できます( 9 * 3 === 27
)。 しかし、結果はゼロのセットで終わります。 何かがおかしかった。 BigInt
もう一度試してみましょう。
1234567890123456789n * 123n; // → 151851850485185185047n
今回は結果が正しいです。
整数の安全な動作の制限はBigInt
には適用されないため、 BigInt
を使用すると、精度の低下を心配することなく長い演算を使用できます。
新しいプリミティブデータ型
BigInt
はJavaScriptの新しいプリミティブデータ型であるため、独自の型を取得し、 typeof
演算子が返すことができます。
typeof 123; // → 'number' typeof 123n; // → 'bigint'
BigInt
は独立したデータ型であるため、 42n !== 42
型のNumber
型のNumber
と厳密に等しくなるBigInt
はありません(たとえば、 42n !== 42
)。 BigInt
とNumber型番号を比較するには、比較を行う前に一方を他方の型に変換するか、型変換比較( ==
)を使用します。
42n === BigInt(42); // → true 42n == 42; // → true
ブール値にキャストする場合(たとえば、 &&
または||
を使用するif
、またはBoolean(int)
式の結果としてなど)、 BigInt
型の数値はNumber
型の数値とまったく同じように動作します。
if (0n) { console.log('if'); } else { console.log('else'); } // → logs 'else', because `0n` is falsy.
オペレーター
BigInt
はほとんどの演算子をサポートしています。 バイナリ+
、 -
、 *
および**
は通常どおり動作します。 /
および%
も機能し、必要に応じて結果を最も近い整数に丸めます。 ビット演算子|
、 &
、 <<
、 >>
および^
は、負の数が追加コードとしてバイナリ形式で表される場合、型Number
数と同様に型BigInt
数で機能します。
(7 + 6 - 5) * 4 ** 3 / 2 % 3; // → 1 (7n + 6n - 5n) * 4n ** 3n / 2n % 3n; // → 1n
単項-
は、負の-42n
値を示すために使用できます(例: -42n
。 単項+
、asm.jsコードを破壊するため、サポートされていません。これは、 +x
常にNumber
または例外を返すことを想定しています。
重要な点は、オペレーションでBigInt
とNumber
を混在させることはできないということです。 暗黙的な変換は情報の損失につながる可能性があるため、これは良いことです。 例を考えてみましょう:
BigInt(Number.MAX_SAFE_INTEGER) + 2.5; // → ??
結果は何と等しくなりますか? 正解はありません。 BigInt
は小数を含めることはできません。また、 Number
は安全な整数の制限を超える大きな数字を正確に含めることはできません。 したがって、 BigInt
およびNumber
操作では、 TypeError
例外がTypeError
ます。
この規則の唯一の例外は、 ===
(前述)、 <
および>=
などの比較演算子です。これらは、精度を失うリスクを伴わない論理値を返すためです。
1 + 1n; // → TypeError 123 < 124n; // → true
注: BigInt
とNumber
は通常混在しないため、既存のコードをNumber
からBigInt
書き換えないでください。 これら2つのタイプのどちらを必要とするかを決定し、使用します。 潜在的に大きな整数で動作する新しいAPIの場合、 BigInt
が最適です。 ただし、整数は安全な範囲内にあることが保証されている値に引き続き使用できます。
また、符号なしの右シフトを実行する>>>
演算子は、 BigInt
数には常に符号が含まれるため、意味がありません。 したがって、 >>>
はBigInt
番号では機能しません。
API
BigInt
いくつかの新しいAPIメソッドが利用可能になりました。
BigInt
グローバルコンストラクターBigInt
Number
コンストラクターに似ています:引数をBigInt
変換します(前述のとおり)。 変換が失敗すると、 RangeError
またはRangeError
例外がスローされます。
BigInt(123); // → 123n BigInt(1.5); // → RangeError BigInt('1.5'); // → SyntaxError
BigInt
値BigInt
指定された有効ビット数に制限できる2つの関数がありますが、その数を符号または符号なしのいずれかと見なします。 BigInt.asIntN(width, value)
型のvalue
数を、符号を考慮してwidth
指定されたビット数に制限しますBigInt.asUintN(width, value)
は、値を符号なしとみなして同じことを行います。 たとえば、64ビットの数値に対する操作が必要な場合、これらのAPIを使用して適切な範囲にとどめることができます。
// `BigInt`, // 64- . const max = 2n ** (64n - 1n) - 1n; BigInt.asIntN(64, max); // → 9223372036854775807n BigInt.asIntN(64, max + 1n); // → -9223372036854775808n // ^ ,
64ビット整数の範囲(値自体に63ビット、文字に1ビット)を超えるBigInt
を渡すとすぐにオーバーフローが発生することに注意してください。
BigInt
使用BigInt
と、他のプログラミング言語で一般的に使用される64ビットの符号付きおよび符号なし整数を正確に表すことができBigInt
。 2つの新しい型付き配列BigInt64Array
およびBigUint64Array
、そのような値のBigUint64Array
を簡素化します。
const view = new BigInt64Array(4); // → [0n, 0n, 0n, 0n] view.length; // → 4 view[0]; // → 0n view[0] = 42n; view[0]; // → 42n
BigInt64Array
は、その値が可能な64ビット符号付き値の制限内であることを保証します。
// `BigInt`, // 64- . const max = 2n ** (64n - 1n) - 1n; view[0] = max; view[0]; // → 9_223_372_036_854_775_807n view[0] = max + 1n; view[0]; // → -9_223_372_036_854_775_808n // ^ ,
BigUint64Array
は、64ビットの符号なしの値に対しても同様に機能します。
BigInt
お楽しみBigInt
!