HOWTO · JavaScript
JavaScript で数値を小数点以下 2 桁に丸める
このチュートリアルでは、JavaScript で数値を小数点以下第 2 位まで四捨五入する方法を説明します。
このページの内容
小数点以下を常に 2 桁で表示する文字列が必要なら、toFixed(2) を使います。戻り値は文字列なので、末尾の 0 も表示されます。数値が必要な場合は、Math.round(value * 100) / 100 を使うか、書式設定した文字列を Number() で変換します。通常の値には便利な方法ですが、JavaScript の数値は 2 進浮動小数点で保存されるため、1.005 などの小数は期待どおりに丸められないことがあります。
toFixed() で数値を書式設定する
数値に toFixed(2) を呼び出すと、小数部分が 2 桁の文字列を取得できます。ラベルや表のセルなどで、5.60 の末尾の 0 も表示したい場合に便利です。ただし、戻り値は文字列です。計算に使うには、数値に変換し直す必要があります。
次の例を実行します。
このセクションのコードと表示されるラベルや出力は英語のままです。
const value = 5.6789;
const fixedText = value.toFixed(2);
const roundedValue = Math.round(value * 100) / 100;
const numericValue = Number(value.toFixed(2));
function roundToTwo(number) {
const shifted = Number(`${number}e2`);
return Number(`${Math.round(shifted)}e-2`);
}
const shiftedValue = roundToTwo(value);
console.log(fixedText, roundedValue, numericValue, shiftedValue);
5.68 5.68 5.68 5.68
値は順に、toFixed() が返す文字列、Math.round() の数値、Number() による変換結果、そして小数点移動ヘルパーの結果です。文字列なのは最初の値だけです。これを Number() で変換すると数値になりますが、末尾の 0 は保持されません。
Math.round() で数値を丸める
100 を掛けると、小数第 2 位が 1 の位に移ります。Math.round() はこの拡大した値を整数に丸め、100 で割ると元の小数の桁に戻ります。結果は数値のままなので後続の計算に便利ですが、表示する小数桁数の情報は持ちません。
Math.round() はちょうど中間の値を正の無限大方向に丸めます。たとえば -1.5 は -1 になるため、負の値が常にゼロから遠ざかる方向に丸められるわけではありません。また、乗算にも浮動小数点演算が使われます。この方法は簡潔ですが、どの入力でも十進数として正確に丸められる保証はありません。
浮動小数点の境界ケースを理解する
JavaScript の Number 型は、値を 2 進浮動小数点で表します。多くの十進小数は 2 進数で正確に表せず、中間計算の結果が意図した十進値よりわずかに小さくなったり大きくなったりすることがあります。よく知られた例が 1.005 です。内部に保存された値は十進数の 1.005 よりわずかに小さいため、1.005.toFixed(2) は "1.00" になることがあり、先に 100 倍してから Math.round() を使っても予想外の結果になる場合があります。
Number.EPSILON は、1 と、その次に表現可能な数値との間隔です。丸める前に加えると、1 付近の一部の入力では役立つことがあります。しかし、表現可能な数値どうしの間隔は数値の大きさによって変わります。そのため、固定のイプシロンを加えても、すべての値や計算過程に起因する問題を解消できるわけではありません。
toPrecision() が指定するのは、有効桁数であり、小数点以下の桁数ではありません。たとえば Number((1.23456).toPrecision(4)).toFixed(2) は "1.24" になりますが、(1.23456).toFixed(2) は "1.23" になります。前者はまず 1.235 に丸め、その中間値をさらに丸めるためです。これは特定の二重丸めの例であり、汎用的な補正方法ではありません。最初の書式設定で、後の丸めに必要な情報が失われることがあります。
小数点移動ヘルパーを使う
上のヘルパーは指数表記を使って小数点の位置を移動し、移動後の値を丸めてから元の位置に戻します。これにより、十進小数に直接 100 を掛けることで起きる予想外の結果を一部避けながら、数値を返せます。別の桁数に丸める場合は指数を調整します。最初の移動にはその桁数を使い、戻すときには符号を反転した値を使います。
このヘルパーは、通常の有限値に使える実用的な選択肢として扱い、十進演算ライブラリの代わりとは考えないでください。浮動小数点表現の影響は残り、極端に大きな値や特殊な値には個別の処理が必要になる場合があります。金額や会計処理で厳密な十進演算が必要なら、用途に合う場合は整数の最小通貨単位を使うか、アプリケーションに適した規則を設定できる十進演算ライブラリを使ってください。表示用に値を書式設定することと、十進数として正確に計算することは別の要件です。
用途に合った方法を選ぶ
桁数を固定した表示文字列が必要なら toFixed(2) を選びます。末尾の 0 が保持され、戻り値は文字列です。通常の浮動小数点演算に適した入力範囲で、簡潔な数値結果が必要なら Math.round(value * 100) / 100 を使います。toFixed() の丸め方を使った後に数値が必要なら Number(value.toFixed(2)) を選べます。ただし、数値は表示形式を保持しません。制約を理解したうえで、小数点移動ヘルパーを数値を得る別の方法として検討できます。
これらの方法のいずれも、JavaScript の数値を正確な十進数に変えるものではありません。画面に表示するときに書式設定してください。厳密な十進数の規則に従って計算する場合は、丸め方と数値表現を明確に定め、アプリケーションで扱う代表的な値を使ってテストしてください。