表題の件を知り、調べてみたまとめになります。
間違いなどあればご指摘いただければ幸いです。
はじめに
BigIntは任意精度の整数型。
TC39(ECMAScriptの策定委員会)で提案中のプロポーザルの一つです。
プロポーザルは0~4の5つのStageがあり、BigIntは現在(2018年7月)Stage3の段階になります。
https://github.com/tc39/proposal-bigint
ChromeやNode.jsで採用されているJavaScriptの実行エンジン「V8」では、
v6.7よりBigIntが実装されています。
https://v8project.blogspot.com/2018/05/v8-release-v67.html
Chrome67〜ではV8 v6.7〜なので、
最新のChromeが入っていればDevToolsのコンソールから簡単に試すことができます。
https://en.wikipedia.org/wiki/Google_Chrome_version_history
Node.js v10.4以降でも使用可能
https://nodejs.org/ja/download/releases/
現在のJavaScript
プリミティブ型
JavaScriptでは以下の6つのプリミティブ型があり、
それ以外はArrayなど含め全てObject型となります。
数値を表す型はnumber型の一つしかありません。
- number
- string
- boolean
- null
- undefined
- Symbol (ECMAScript2015で追加)
number, string, booleanはそれぞれラッパー型であるNumber,String,Booleanがあり(全てObject型)、区別のためプリミティブ型は小文字で表記します。
number型
number型はIEEE754で規定されている倍精度浮動小数点数です。
よって、正確に扱える数値の範囲は、-(2の53乗 - 1) ~ (2の53乗 - 1)となります。
// 正確に扱える最大整数値(9_007_199_254_740_991)
const max = Number.MAX_SAFE_INTEGER;
// 1を足すことは可能。 --> 9007199254740992
console.log(max + 1);
// 9007199254740993のはずだが... --> 9007199254740992
console.log(max + 2);
// よって以下はtrueとなる --> true
console.log(max + 1 === max + 2);
BigInt
これまでnumber型範囲以上の数値を扱うにはサードパーティのライブラリを用いる必要がありましたが、
今後BigIntが広く使用可能となれば、ビルトインオブジェクトの範囲で対応可能となります。
下記記事内の画像では、パフォーマンスも向上されることが確認できます。
https://developers.google.com/web/updates/2018/05/bigint
(ただし、Stage3なので却下される可能性はあり)
使用方法
- リテラルは数値の後ろにnを付与
- グローバル関数BigInt()で、number型(またはstring型) -> BigInt型の変換
// --> 9007199254740993n
console.log(BigInt(Number.MAX_SAFE_INTEGER) + 2n);
console.log(BigInt("9007199254740991") + 2n);
// 2,8,16進数表記のリテラルも可能 --> 4n, 64n, 256n
console.log(0b100n);
console.log(0o100n);
console.log(0x100n);
// ただし小数はBigIntで表現できないのでエラー
// エラー(RangeError)
console.log(BigInt(2.5));
// エラー(SyntaxError)
console.log(BigInt("2.5"));
// プリミティブ型なのでtypeof演算子にも対応 --> "bigint"
console.log(typeof 2n);
- 演算子 + - * **は想定通りに働く
- 演算子 / % は0へ丸められる場合がある
// number型の場合 --> 2.5
console.log(10 / 4);
// BigInt型の場合 --> 2n
console.log(10n / 4n);
- BigIntとnumber型の演算は基本的にエラー
- 例外として比較演算子はエラーとならない
- 緩い比較演算子や不等号では片方の型に変換されて評価される
- 0nはnumber型の0同様にfalseと評価される
// エラー(TypeError)
console.log(2n + 2);
// --> false
console.log(2n === 2);
// --> true
console.log(2n == 2);
// --> true
console.log(3n >= 2);
// --> "0n evaluates to false"
if (0n) {
console.log("0n evaluates to true");
} else {
console.log("0n evaluates to false");
}
その他API
以下のAPIで、BigIntを任意のビット範囲に絞ったリ、64ビットの配列を作成可能。
(いまいち用途を分かっていないです…)
- BigInt.asIntN(width, value)
- BigInt.asUintN(width, value)
- BigInt64Array(size) (コンストラクタ)
- BigUInt64Array(size) (コンストラクタ)
// 符号付64bit整数の最大値(9_223_372_036_854_775_807)
const max = 2n ** (64n - 1n) - 1n;
const v = BigInt.asIntN(64, max + 1n);
// オーバフローして負の値に --> -9223372036854775808n
console.log(v);
// [0n, 0n, 0n, 0n]
const array = new BigInt64Array(4);
array[0] = max + 1n;
// オーバフローして負の値に --> -9223372036854775808n
console.log(array[0]);