タイトル: Math (JS ビルトイン)
SEOタイトル: JavaScript Math オブジェクト完全リファレンス(PI/abs/random/三角関数/暗号乱数)
| この記事の要点 |
|
Math は静的オブジェクト
Math は数値計算用の静的プロパティ・メソッドをまとめたシングルトン。new Math() はできません。
typeof Math; // "object"
Math.constructor; // undefined
new Math(); // TypeError: Math is not a constructor
定数
| 定数 | 値 | 意味 |
|---|---|---|
Math.PI | 3.141592653589793 | 円周率π |
Math.E | 2.718281828459045 | ネイピア数 e |
Math.LN2 | 0.6931... | ln(2) |
Math.LN10 | 2.3025... | ln(10) |
Math.LOG2E | 1.4426... | log₂(e) |
Math.LOG10E | 0.4342... | log₁₀(e) |
Math.SQRT2 | 1.4142... | √2 |
Math.SQRT1_2 | 0.7071... | √(1/2) |
絶対値・符号・丸め
Math.abs(-3.5); // 3.5 絶対値
Math.sign(-7); // -1 符号 (-1 / 0 / 1)
Math.sign(0); // 0
Math.sign(3); // 1
// 丸め4種
Math.floor(2.9); // 2 切り下げ(負の無限大方向)
Math.floor(-2.1); // -3
Math.ceil(2.1); // 3 切り上げ(正の無限大方向)
Math.ceil(-2.9); // -2
Math.round(2.5); // 3 四捨五入(.5は正方向へ)
Math.round(-2.5); // -2 ★ -3 ではない
Math.trunc(2.9); // 2 小数切り捨て(0方向)
Math.trunc(-2.9); // -2
Math.round の罠(負の .5)
多くの言語は「銀行家の丸め (round-half-to-even)」を採用しますが、Math.round は「.5 は常に正の無限大方向」。負数で直感に反します:
Math.round(0.5); // 1
Math.round(1.5); // 2
Math.round(-0.5); // 0 ← -1 ではない!
Math.round(-1.5); // -1 ← -2 ではない!
最小・最大
Math.min(1, 2, 3); // 1
Math.max(1, 2, 3); // 3
Math.min(); // Infinity(引数なし)
Math.max(); // -Infinity
// 配列の最小・最大(スプレッド構文)
const arr = [3, 1, 4, 1, 5, 9, 2, 6];
Math.min(...arr); // 1
Math.max(...arr); // 9
// 巨大配列は ...arr でスタックオーバーフロー注意 → reduce で安全
arr.reduce((a, b) => Math.min(a, b), Infinity);
べき乗・平方根
Math.pow(2, 10); // 1024 2^10
2 ** 10; // 1024 ES2016 べき乗演算子
Math.sqrt(16); // 4 平方根
Math.cbrt(27); // 3 立方根
Math.hypot(3, 4); // 5 ピタゴラス √(3²+4²)
Math.exp(1); // 2.718... e^x
Math.expm1(1); // 1.718... e^x - 1 (精度向上)
対数
Math.log(Math.E); // 1 自然対数 ln(x)
Math.log2(8); // 3 log₂(x)
Math.log10(1000); // 3 log₁₀(x)
Math.log1p(0); // 0 log(1+x) 精度向上版
三角関数
引数・戻り値はすべてラジアン。度との変換が必要です:
const toRad = deg => deg * Math.PI / 180;
const toDeg = rad => rad * 180 / Math.PI;
Math.sin(toRad(30)); // 0.5
Math.cos(toRad(60)); // 0.5
Math.tan(toRad(45)); // 0.9999... (≈1、浮動小数誤差)
// 逆三角
Math.asin(0.5); // 0.5236 (=π/6)
Math.acos(0.5); // 1.0471 (=π/3)
Math.atan(1); // 0.7853 (=π/4)
// atan2 は (y, x) の象限を考慮した角度
Math.atan2(1, 1); // π/4
Math.atan2(1, -1); // 3π/4
Math.atan2(-1, -1); // -3π/4
Math.atan2(-1, 1); // -π/4
// 双曲線関数
Math.sinh(1); Math.cosh(1); Math.tanh(1);
乱数: Math.random()
Math.random(); // 0 以上 1 未満
Math.floor(Math.random() * 10); // 0〜9 の整数
Math.floor(Math.random() * (max - min + 1)) + min; // min〜max の整数
// 配列からランダム1つ
const arr = ['a', 'b', 'c'];
arr[Math.floor(Math.random() * arr.length)];
// シャッフル(Fisher-Yates)
function shuffle(a) {
for (let i = a.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[a[i], a[j]] = [a[j], a[i]];
}
return a;
}
暗号用途には Crypto API
Math.random() は予測可能で暗号には使えません。トークン生成・パスワード・暗号鍵は crypto.getRandomValues か crypto.randomUUID を使います:
// Web Crypto API(ブラウザ・Node.js 19+ グローバル crypto)
const arr = new Uint32Array(1);
crypto.getRandomValues(arr);
const n = arr[0]; // 0 〜 2^32-1 の安全な乱数
// UUID v4
crypto.randomUUID(); // "e7b7e5c3-1234-..."
// Node.js では別途
const crypto = require('crypto');
const buf = crypto.randomBytes(32); // 256bit 暗号トークン
crypto.randomUUID(); // Node 14.17+
その他便利関数
Math.clz32(1); // 31 32bit 整数の先頭ゼロ数
Math.fround(1.1); // float32 精度に丸める
Math.imul(0xffffffff, 5); // C スタイルの 32bit 整数乗算
// よく使う組み合わせ: 範囲クランプ
const clamp = (x, lo, hi) => Math.max(lo, Math.min(hi, x));
clamp(150, 0, 100); // 100
clamp(-5, 0, 100); // 0
// 範囲外チェック
const inRange = (x, lo, hi) => x >= lo && x <= hi;
浮動小数点の罠
JS の数値は IEEE 754 double。0.1 + 0.2 !== 0.3 は有名です。Math 系メソッドでも誤差は残ります:
0.1 + 0.2; // 0.30000000000000004
Math.tan(Math.PI / 4); // 0.9999999999999999 (理論値 1)
// 比較は誤差を許容
Math.abs((0.1 + 0.2) - 0.3) < Number.EPSILON; // true
// 整数演算で済むなら BigInt も検討
10n ** 18n; // 1000000000000000000n
FAQ
Q: 整数の四捨五入で (0.5) の挙動が他言語と違う
A: Math.round は「.5 は正方向」固定。JavaScript 標準にこの挙動を変える方法はありません。銀行家丸めは自作するか Intl.NumberFormat を使います。
Q: Math.random の品質は?
A: V8 は xorshift128+ ベース。統計的には十分ですが予測可能。ゲーム・統計はOK、認証は NG。
Q: 1〜100 の整数乱数
A: Math.floor(Math.random() * 100) + 1。よく間違える: Math.random() * 99 + 1 は 100 が出ない。