Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

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

はじめに

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

引用元

gtnao0219
中目黒のスタートアップで「trocco」という分析基盤向けのデータ統合SaaSを開発してます。
https://www.blog.gtnao.com
primenumber_inc
ビッグデータ分析基盤向けデータ統合自動化サービス「trocco」などを提供する、データエンジニアリングスタートアップ
https://primenumber.co.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away