概要
JavaScriptの数値型 (Number型) は、IEEE 754 倍精度浮動小数点数として実装されており、64ビットで符号部 (1ビット)、指数部 (11ビット)、仮数部 (52ビット) で構成されている。
JavaScriptは単一の数値型を使用しており、整数と小数を区別しない。
安全に扱える整数範囲は、 から であり、この範囲を超える大きな整数を扱う場合はBigInt型の使用が必要となる。
数値を扱う上で重要な概念として、以下が挙げられる。
- Number型の特性 (IEEE 754、安全な整数範囲、浮動小数点精度問題)
- 数値リテラル (10進数、16進数、8進数、2進数、指数表記)
- 算術演算子 (基本演算子、インクリメント / デクリメント、代入演算子)
- Math オブジェクト (数学定数、丸め処理、最大値 / 最小値、乱数生成)
- 数値の変換と判定 (Number(), parseInt(), parseFloat(), 判定メソッド)
- BigInt型 (任意精度整数、Number との違いと使い方)
Number型の特性
JavaScriptのNumber型は、国際標準であるIEEE 754の倍精度形式に従って実装されている。
IEEE 754倍精度浮動小数点
64ビットの構成は以下の通りである。
- 符号部 (1ビット)
- 正負を表現する
- 指数部 (11ビット)
- -1022〜1023の範囲の指数を表現する
- 仮数部 (52ビット)
- 有効数字を表現する。
- ケチ表現を使用する。
この形式により、10進数での有効桁数は約15.95桁となる。
Numberオブジェクトの重要なプロパティを以下に示す。
| 定数 | 説明 | 値 |
|---|---|---|
Number.MAX_VALUE |
表現可能な最大正の数 | 約 1.79e+308 |
Number.MIN_VALUE |
0ではない、0に最も近い正の数 | 約 5e-324 |
Number.EPSILON |
表現可能な最小の差 |
安全な整数の範囲
JavaScriptで安全に扱える整数の範囲は、以下の定数で定義されている。
| 定数 | 説明 | 値 |
|---|---|---|
Number.MAX_SAFE_INTEGER |
安全に表現可能な最大の整数 | |
Number.MIN_SAFE_INTEGER |
安全に表現可能な最小の整数 |
安全 とは、ビット演算や比較において一意に表現できることを意味する。
この範囲を超えると、隣り合う整数が同じ浮動小数点数で表現されるようになり、正確な計算ができなくなる。
// 安全な整数範囲の確認
console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991
console.log(Number.MIN_SAFE_INTEGER); // -9007199254740991
// 範囲を超えると正確な計算ができなくなる
9007199254740992 === 9007199254740993 // true (不正な結果)
// 安全な整数かどうかの確認
Number.isSafeInteger(9007199254740991) // true
Number.isSafeInteger(9007199254740992) // false
浮動小数点の精度問題
JavaScriptの浮動小数点数は、2進法で有限のビット数を使用するため、10進数の小数を正確に表現できない場合がある。
代表的な例として、0.1 + 0.2 の計算が挙げられる。
// 精度問題の例
console.log(0.1 + 0.2); // 0.30000000000000004
console.log(0.1 + 0.2 === 0.3); // false
// Number.EPSILONを使用した許容範囲内の比較
function almostEqual(a, b) {
return Math.abs(a - b) < Number.EPSILON;
}
console.log(almostEqual(0.1 + 0.2, 0.3)); // true
この問題に対処するには、Number.EPSILON を使用して許容範囲内かどうかを判定する方法が有効である。
特殊な値 (NaN / Infinity)
JavaScriptには、通常の数値以外の特殊な値が存在する。
NaN(Not a Number)- 数学的に定義されない計算結果
- 例: 0/0、Math.sqrt(-1)
- 唯一、自身と等しくない値である
NaN !== NaN
Infinity- 正の無限大
- 1/0 で返される
-Infinity- 負の無限大
- -1/0 で返される
-0(負のゼロ)- 0 と異なる符号を持つ。
- 1/-0 は、-Infinityとなる
Numberオブジェクトには、これらに対応するプロパティも存在する。
Number.NaNNumber.POSITIVE_INFINITYNumber.NEGATIVE_INFINITY
// NaNの特性
console.log(NaN === NaN); // false (NaN は自身と等しくない)
console.log(Number.isNaN(NaN)); // true (正しい判定方法)
console.log(0 / 0); // NaN
console.log(Math.sqrt(-1)); // NaN
// Infinityの特性
console.log(1 / 0); // Infinity
console.log(-1 / 0); // -Infinity
console.log(Infinity + 1); // Infinity
// -0の特性
console.log(-0 === 0); // true
console.log(1 / -0); // -Infinity (Infinity と異なる)
数値リテラル
JavaScriptは、複数の記法で数値を表現できる。
// 10進数
const decimal = 123;
const float = 3.14;
const negative = -456;
// 16進数 (0xプレフィックス)
const hex1 = 0xFF; // 255
const hex2 = 0x1A; // 26
const hex3 = 0xDEADBEEF; // 3735928559
// 8進数 (0oプレフィックス、小文字推奨)
const oct1 = 0o755; // 493
const oct2 = 0o644; // 420
// 2進数 (0bプレフィックス)
const bin1 = 0b1010; // 10
const bin2 = 0b11111111; // 255
// 指数表記
const exp1 = 1e3; // 1000 (10^3)
const exp2 = 5e-2; // 0.05 (5 * 10^-2)
const exp3 = 2.5e2; // 250
// アンダースコア区切り (ES2021以降)
const million = 1_000_000; // 1000000
const hexColor = 0xFF_FF_FF_FF; // 4294967295
const binByte = 0b1111_0000; // 240
const pi = 3.14_15_92; // 3.141592
アンダースコア区切りには以下の制限がある。
- 先頭や末尾には配置できない。
- 小数点の直前 / 直後には配置できない。
- 2個以上連続して使用できない。
算術演算子
JavaScriptには、数値計算のための様々な演算子が用意されている。
基本的な算術演算子
| 演算子 | 名称 | 説明 | 使用例 | 結果 |
|---|---|---|---|---|
+ |
加算 | 2つの数値を加える | 10 + 5 | 15 |
- |
減算 | 2つの数値の差を求める | 10 - 3 | 7 |
* |
乗算 | 2つの数値を掛ける | 4 * 3 | 12 |
/ |
除算 | 2つの数値を割る | 15 / 3 | 5 |
% |
剰余 | aをbで除算した余り | 17 % 5 | 2 |
** |
冪乗 | aのb乗 (ES2016 以降) | 2 ** 10 | 1024 |
console.log(10 + 5); // 15
console.log(10 - 3); // 7
console.log(4 * 3); // 12
console.log(15 / 3); // 5
console.log(17 % 5); // 2 (余り)
console.log(2 ** 3); // 8 (2^3)
console.log(2 ** 10); // 1024
インクリメント / デクリメント
インクリメント演算子 (++) は変数を1増加させ、デクリメント演算子 (--) は変数を1減少させる。
前置と後置で動作が異なる点に注意が必要である。
++x(前置インクリメント)- 変数を増加させた後、増加後の値を返す
x++(後置インクリメント)- 元の値を返してから、その後で変数を増加させる
--x(前置デクリメント)- 変数を減少させた後、減少後の値を返す
x--(後置デクリメント)- 元の値を返してから、その後で変数を減少させる
// 前置インクリメント
let x = 5;
console.log(++x); // 6 (増加後の値を返す)
console.log(x); // 6
// 後置インクリメント
let y = 5;
console.log(y++); // 5 (元の値を返す)
console.log(y); // 6 (その後増加)
// 代入時の動作の違い
let a = 5;
let b = ++a; // b = 6, a = 6 (前置: 増加後の値を代入)
let c = 5;
let d = c++; // d = 5, c = 6 (後置: 元の値を代入)
// デクリメントの例
let n = 5;
console.log(--n); // 4 (前置)
let m = 5;
console.log(m--); // 5 (後置)
console.log(m); // 4
代入演算子
下表に、算術演算と代入を組み合わせた複合代入演算子を示す。
| 演算子 | 同等の式 | 説明 |
|---|---|---|
a += b |
a = a + b | 加算して代入 |
a -= b |
a = a - b | 減算して代入 |
a *= b |
a = a * b | 乗算して代入 |
a /= b |
a = a / b | 除算して代入 |
a %= b |
a = a % b | 剰余を代入 |
a **= b |
a = a ** b | 冪乗して代入 (ES2016 以降) |
let x = 10;
x += 5; // x = 15
x -= 3; // x = 12
x *= 2; // x = 24
x /= 4; // x = 6
x %= 4; // x = 2
x **= 3; // x = 8
Mathオブジェクト
Math は組み込みオブジェクトであり、数学的な計算や定数を提供する。
コンストラクタではなく、全てのプロパティとメソッドは静的 (static) である。
定数
Mathオブジェクトが提供する主要な数学定数を以下に示す。
Math.PI- 円周率 (π、約 3.141592653589793)
Math.E- ネイピア数 (e、自然対数の底、約 2.718281828459045)
Math.SQRT2- 2の平方根 (約 1.4142135623730951)
Math.LN2- (約 0.6931471805599453)
Math.LN10- 10の自然対数 (約 2.302585092994046)
Math.LOG2E- (約 1.4426950408889634)
Math.LOG10E- (約 0.4342944819032518)
Math.SQRT1_2- (約 0.7071067811865476)
主要なメソッド
丸め処理
Math.floor(x)- x以下の最大整数を返す (切り捨て)
Math.ceil(x)- x以上の最小整数を返す (切り上げ)
Math.round(x)- xを最も近い整数に丸める (四捨五入)
Math.trunc(x)- 小数部を切り落とし、整数部のみを返す
Math.floor(4.7) // 4 (切り捨て)
Math.floor(-4.7) // -5 (負の数では注意)
Math.ceil(4.2) // 5 (切り上げ)
Math.round(4.5) // 5 (四捨五入)
Math.round(4.4) // 4
Math.trunc(4.9) // 4 (小数部を削除)
Math.trunc(-4.9) // -4 (負の数でも0方向に丸める)
Math.trunc() と Math.floor() の違いは、負の数の扱いにある。
負の数に対して、Math.floor() はより小さい整数を返すが、Math.trunc() は0に向かって丸める。
最大値と最小値
Math.max(a, b, c, ...)- 複数の数値から最大値を返す。
- 引数なしの場合は、
-Infinityを返す。
Math.min(a, b, c, ...)- 複数の数値から最小値を返す。
- 引数なしの場合は、
Infinityを返す。
Math.max(1, 5, 3) // 5
Math.min(1, 5, 3) // 1
Math.max(-1, -5, -3) // -1
// 配列から最大値を取得する場合 (スプレッド演算子を使用)
const numbers = [1, 5, 3, 2, 8];
Math.max(...numbers) // 8
Math.min(...numbers) // 1
乱数
Math.random() は、0以上1未満の疑似乱数を返す。
指定した範囲の乱数を生成するには、以下のパターンを使用する。
// 0以上1未満の乱数
Math.random(); // 例: 0.7341234...
// minからmaxまでの整数乱数 (min と max を含む)
function randomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
randomInt(1, 10) // 1~10 の整数
randomInt(1, 6) // サイコロ (1~6)
// minからmaxまでの浮動小数点数乱数
function randomFloat(min, max) {
return Math.random() * (max - min) + min;
}
randomFloat(0, 100) // 0.0~100.0 の小数
冪乗と平方根
Math.pow(base, exponent)- baseのexponent乗を返す。
**演算子の代替
Math.sqrt(x)- xの平方根を返す
Math.cbrt(x)- xの立方根を返す
Math.abs(x)- xの絶対値を返す
Math.pow(2, 3) // 8 (2^3、**演算子と同等)
2 ** 3 // 8 (モダンな方法)
Math.sqrt(16) // 4
Math.sqrt(2) // 1.4142135623730951
Math.cbrt(8) // 2
Math.cbrt(27) // 3
Math.abs(-5) // 5
Math.abs(5) // 5
その他の主要なメソッドとして、以下がある。
Math.sign(x)- xの符号を返す。
- -1、-0、0、1、NaNのいずれか
Math.log(x)- xの自然対数を返す。
Math.log2(x)- xの2を底とする対数を返す。
Math.log10(x)- xの10を底とする対数を返す。
数値の変換と判定
JavaScriptでは、文字列等の値を数値型に変換したり、数値の性質を判定したりするための関数やメソッドが用意されている。
文字列から数値への変換
Number(value)- 値を数値型に変換する。
- 変換できない場合は、NaNを返す。
parseInt(string, radix)- 文字列を解析して、指定された基数の整数値を返す。
parseFloat(string)- 文字列を解析して、浮動小数点数を返す。
// Number()の変換例
Number("123") // 123
Number("3.14") // 3.14
Number("0xFF") // 255
Number(true) // 1
Number(false) // 0
Number(null) // 0
Number(undefined) // NaN
Number("") // 0
Number("abc") // NaN
// parseInt()の使用例
parseInt("123", 10) // 123 (10進数)
parseInt("FF", 16) // 255 (16進数)
parseInt("1111", 2) // 15 (2進数)
parseInt("17", 8) // 15 (8進数)
parseInt("15px", 10) // 15 (無効な文字で停止)
parseInt("xyz") // NaN
parseInt("1.9", 10) // 1 (小数部は切り捨て)
// parseFloat()の使用例
parseFloat("3.14") // 3.14
parseFloat("1e3") // 1000
parseFloat("1.5e2") // 150
parseFloat("10px") // 10 (無効な文字で停止)
parseInt() を使用する時は、必ず基数 (radix) を第2引数として指定することが推奨される。
また、parseInt() を数値の丸め処理に使用してはならない。
大きな数値では指数表記による予期しない結果が生じる可能性があるため、Math.floor() や Math.trunc() を使用すること。
数値の判定メソッド
| メソッド | 説明 | 型変換 |
|---|---|---|
Number.isNaN(x) |
値がNaNであるかを判定する | なし (推奨) |
isNaN(x) |
値がNaNであるかを判定する | あり (非推奨) |
Number.isFinite(x) |
値が有限数であるかを判定する | なし (推奨) |
isFinite(x) |
値が有限数であるかを判定する | あり (注意が必要) |
Number.isInteger(x) |
値が整数であるかを判定する | なし |
Number.isSafeInteger(x) |
値が安全な整数範囲内であるかを判定する | なし |
Number.isNaN() とグローバルの isNaN() は動作が異なる。
Number.isNaN() は型変換を行わないため、正確な判定が可能であり、こちらの使用が強く推奨される。
// Number.isNaN() (型変換なし、推奨)
Number.isNaN(NaN); // true
Number.isNaN(0 / 0); // true
Number.isNaN("NaN"); // false (文字列)
Number.isNaN(undefined); // false
// グローバルのisNaN() (型変換あり、注意が必要)
isNaN(NaN); // true
isNaN("NaN"); // true (文字列が NaN に変換される)
isNaN(undefined); // true (undefined が NaN に変換される)
isNaN(null); // false (null が 0 に変換される)
// Number.isFinite()の例
Number.isFinite(42); // true
Number.isFinite(Infinity); // false
Number.isFinite(NaN); // false
Number.isFinite("42"); // false (文字列は false)
// Number.isInteger()の例
Number.isInteger(42); // true
Number.isInteger(42.0); // true (42.0 は 42 として表現)
Number.isInteger(3.14); // false
// Number.isSafeInteger() の例
Number.isSafeInteger(42); // true
Number.isSafeInteger(9007199254740991); // true (MAX_SAFE_INTEGER)
Number.isSafeInteger(9007199254740992); // false (超過)
BigInt
BigInt は、任意精度の整数を表すプリミティブ型であり、ES2020以降で利用可能である。
Number.MAX_SAFE_INTEGER を超える大きな整数を正確に表現できる。
BigInt値は、整数リテラルの末尾に n を付ける、または、BigInt() 関数で作成する。
// リテラル記法 (末尾にn)
const big1 = 123n;
const big2 = 9007199254740991n;
const big3 = -123n;
// BigInt() 関数 (文字列または Number から変換)
const big4 = BigInt("9007199254740991");
const big5 = BigInt(123);
// 異なる進法でのBigIntリテラル
const hex = 0xFFFFFFFFn; // 16進数
const bin = 0b11111111n; // 2進数
const oct = 0o777n; // 8進数
// typeofの結果
typeof 123n === "bigint" // true
typeof 123 === "number" // true
BigIntでは、算術演算子 (+、-、*、/、%、**) およびビット演算子が使用できる。
ただし、除算の結果は小数部が切り捨てられる。
BigIntとNumberを混合した算術演算は、TypeError を発生させるため、同じ型を使用しなければならない。
比較演算子 (==、<、> 等) は、BigIntとNumberの混合で使用できる。
// BigIntの演算
5n / 2n // 2n (小数部は切り捨て)
2n ** 53n // 9007199254740992n
17n % 5n // 2n
// BigInt と Number の混合はエラー
// 1n + 2 // TypeError: Cannot mix BigInt and other types
// 5n * 2 // TypeError
// 比較は可能
1n < 2 // true
1n == 1 // true (型変換を伴う比較)
1n === 1 // false (型変換を伴わない比較)
// 型変換による回避方法
BigInt(2) + 1n // 3n (NumberをBigIntに変換)
Number(1n) + 2 // 3 (BigIntをNumberに変換)
Mathオブジェクトのメソッドは、BigIntをサポートしない。
BigInt値をMathメソッドに渡すと TypeError が発生するため、冪乗には ** 演算子を使用する等、代替の方法を利用すること。
BigIntの主な使用場面は以下の通りである。
- 暗号化関連 (非常に大きい素数の取り扱い)
- 大規模な ID システム (64ビット以上の ID)
- 金融計算 (正確な大数計算が必要な場合)
- ナノ秒単位のタイムスタンプ
関連情報
- JavaScriptの基礎 - 変数宣言
- let / const / varの宣言方法、スコープ、ホイスティング
- JavaScriptの基礎 - プリミティブ型
- 7つのプリミティブ型、typeof演算子、型の自動変換
- JavaScriptの基礎 - 文字列
- テンプレートリテラル、文字列メソッド、タグ付きテンプレートリテラル
- JavaScriptの基礎 - 比較演算子と論理演算子
- === / ==の違い、短絡評価、Null合体演算子、オプショナルチェーン