LoginSignup
2

More than 5 years have passed since last update.

Chrome 67からJavaScriptのプリミティブ型BigIntが使用可能に

Last updated at Posted at 2018-07-15

表題の件を知り、調べてみたまとめになります。
間違いなどあればご指摘いただければ幸いです。

はじめに

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]);

引用元

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
2