JavaScriptのMath.log2():2倍と半分を対称な数値で比較する
Math.log2()で倍率を比較し、2倍と半分を対称な値に変換する方法を解説。引数・戻り値、ブラウザーとNode.jsでの実行手順、入力検証や計算精度の注意点を学べます。
目的:倍率の変化を同じ尺度で比較する
処理時間が100ミリ秒から200ミリ秒になった場合は2倍、100ミリ秒から50ミリ秒になった場合は半分です。倍率をそのまま並べると、それぞれ2と0.5になり、変化なしを表す1からの距離がそろいません。
Math.log2()を使うと、2倍を1、変化なしを0、半分を-1に変換できます。4倍なら2、4分の1なら-2です。掛け算による変化を、足し算で比較できる尺度へ置き換えられます。
この記事では、処理時間の比較を題材に、倍率を底が2の対数へ変換します。正の値どうしの相対的な変化を比較したい場合に向く方法です。元の処理時間も残せば、変化の大きさと実際の待ち時間を両方確認できます。
動作環境と対応バージョン
Math.log2()はJavaScriptの標準組み込みメソッドです。ブラウザーとNode.jsの両方で利用でき、外部パッケージやDOMは必要ありません。
2026年10月21日時点で参照したMDNのMath.log2()リファレンスでは、2015年7月以降、主要ブラウザーで広く利用可能な機能とされています。本記事のブラウザー向け手順は、現在のChrome、Edge、Firefox、Safariを対象にします。
Node.jsでは、本記事の実行対象を22系以降とします。これは記事で使う環境の範囲であり、APIの初対応バージョンを意味しません。実験的な機能を有効にするフラグは不要です。Node.jsの標準機能と実行フラグの関係は公式のECMAScript解説も参照してください。
古いブラウザーや組み込みの実行環境を対象にする場合は、typeof Math.log2 === "function"で利用可能か確認できます。後述のコードにも、この確認を含めます。
引数と戻り値を理解する
基本構文
Math.log2(x)引数のxは、対数を求める数値です。戻り値はnumberで、「2を何乗するとxになるか」を表します。たとえば2の3乗は8なので、Math.log2(8)は3です。
Mathはコンストラクターではありません。インスタンスを作らず、Math.log2()の形で呼び出します。
値の範囲と特別な結果
xが1なら、戻り値は0です。xが1より大きければ、戻り値は正になります。xが0より大きく1未満なら、戻り値は負になります。xが0または-0なら、戻り値は-Infinityです。xが負の数なら、戻り値はNaNです。xがInfinityなら、戻り値はInfinityです。
これらの特殊値は、MDNの使用例でも確認できます。負数を渡しても、そのことだけで例外になるわけではありません。業務上受け付けない値は、呼び出す側で検証する必要があります。
コピーして試す:処理時間の倍率を変換する
次のコードは、以前と現在の処理時間から倍率を求め、その倍率をMath.log2()へ渡します。入力は有限の正の数値に限定します。
自己完結したコード
Node.jsで試す場合は、次の内容をlog-two-demo.cjsという名前で保存してください。ブラウザーでは、コード全体を開発者ツールのコンソールで実行できます。
(() => {
"use strict";
if (typeof Math.log2 !== "function") {
console.error("この環境ではMath.log2()を利用できません");
return;
}
function compareDuration(previous, current) {
for (const value of [previous, current]) {
if (typeof value !== "number" || !Number.isFinite(value)) {
throw new TypeError("処理時間は有限の数値にしてください");
}
if (value <= 0) {
throw new RangeError("処理時間は0より大きくしてください");
}
}
const ratio = current / previous;
if (!Number.isFinite(ratio) || ratio <= 0) {
throw new RangeError("倍率が計算可能な範囲を外れています");
}
return { ratio, logRatio: Math.log2(ratio) };
}
const samples = [
{ label: "変化なし", previous: 100, current: 100 },
{ label: "2倍", previous: 100, current: 200 },
{ label: "半分", previous: 100, current: 50 },
{ label: "4倍", previous: 100, current: 400 },
{ label: "4分の1", previous: 100, current: 25 },
{ label: "不正な入力", previous: 0, current: 100 },
];
for (const sample of samples) {
try {
const result = compareDuration(sample.previous, sample.current);
console.log(
`${sample.label}: 倍率=${result.ratio}, 対数=${result.logRatio}`
);
} catch (error) {
if (!(error instanceof Error)) {
throw error;
}
console.log(`${sample.label}: ${error.name}: ${error.message}`);
}
}
})();ブラウザーでの実行方法
Chromeなどで空のタブを開き、開発者ツールからコンソールを選択します。上のJavaScript全体を入力して実行してください。HTMLファイルの作成やサーバーの起動は不要です。
コードを即時実行関数で囲んでいるため、再実行してもトップレベルのconst宣言が衝突しません。コンソールが表示する評価結果のundefinedは、後述のログとは別の表示です。
Node.jsでの実行方法
Node.js 22系以降を用意し、ターミナルでlog-two-demo.cjsを保存したフォルダーへ移動して、次を実行します。
node --version
node log-two-demo.cjs追加のインストール作業やpackage.jsonは必要ありません。.cjsを使うことで、周囲のプロジェクトのモジュール設定による影響を避けています。ファイル名を指定して実行する手順はNode.js公式ガイドに沿っています。
期待出力と計算の読み方
対応環境では、次のログが出る想定です。これはコードと仕様から導いた期待出力であり、実機での実行確認結果ではありません。
変化なし: 倍率=1, 対数=0
2倍: 倍率=2, 対数=1
半分: 倍率=0.5, 対数=-1
4倍: 倍率=4, 対数=2
4分の1: 倍率=0.25, 対数=-2
不正な入力: RangeError: 処理時間は0より大きくしてくださいcurrent / previousなので、現在の処理時間が長くなると正、短くなると負です。この例では正方向が遅延の増加を意味します。処理件数など、大きいほうが望ましい指標では評価の向きが変わるため、画面上に指標の意味を明記してください。
logRatioが2だからといって、処理時間が2ミリ秒増えたわけではありません。基準の4倍になったという意味です。単位付きの差分と対数による倍率は、別の情報として扱います。
失敗例と制約
try/catchだけではNaNを防げない
次のコードは例外を投げず、NaNを出力します。
try {
console.log(Math.log2(-8));
} catch (error) {
console.log("計算に失敗しました");
}catchへ入ることを前提にしていると、不正な計算結果が後続処理へ流れます。実用例で型、有限性、正数という条件を先に確認したのは、この問題を防ぐためです。文字列の"100"も実用例では拒否し、入力形式の誤りを見逃さない設計にしています。
ゼロを勝手に置き換えない
処理時間がゼロだった場合、実用例はRangeErrorにします。ゼロを小さな正数へ置き換えれば計算はできますが、選んだ数によって結果が大きく変わります。計測の分解能より短かった値なのか、欠測をゼロで表しているのかを確認し、別の表示状態として扱うほうが判断しやすくなります。
割り算と丸め誤差にも注意する
有限の正数どうしでも、極端な値を割ると倍率がInfinityになったり、非常に小さくなって0になったりします。実用例は割り算の後も検証し、その範囲を扱わない方針です。
また、一般の入力では計算結果が近似値になります。対数が整数かどうかの厳密比較や、境界ぎりぎりの値による区分には注意してください。表示用に小数桁をそろえる場合も、判定には丸める前の値を使い、許容誤差は計測精度に基づいて決めます。
この処理は同期処理です。Promiseやawaitは不要で、実用例は各データの例外をその場で処理しているため、不正な1件があっても次のデータへ進みます。
活用事例と導入時の改善案
同じ種類の処理について、変更前後の所要時間を比較するレポートに使えます。2倍と半分、4倍と4分の1を対称に表せるため、基準からの相対的な変化を並べやすくなります。
ただし、元の値の重要性は残ります。1ミリ秒から2ミリ秒への変化と、1秒から2秒への変化は、対数上ではどちらも1です。利用者への影響まで同じとは判断できません。
実務へ導入するなら、最初は元の処理時間、倍率、対数の3つを併記する方法を提案します。対数だけでは読み取りに慣れが必要ですが、元データを併記すれば結果の意味を確かめられるためです。まず比較条件をそろえた小さなレポートで試し、判断に役立つことを確認してから表示へ組み込みましょう。
公式参考資料
Googleの優先するニュース提供元にSEの部屋を追加
Googleで、いつも読みたい情報源を選べます。登録可否はGoogleの画面で確認できます。
候補にSEの部屋が表示されない場合は、まだ追加できません。