金額の計算、パーセンテージの表示、センサー値の丸めなど、四捨五入はプログラミングで最も頻繁に行われる数値操作の一つです。JavaScript では Math.round が基本ですが、小数桁数を指定した四捨五入や浮動小数点の誤差対策など、実務で押さえておくべきポイントがあります。
・Math.round で整数に四捨五入する基本
・小数第 N 位で四捨五入する方法
・toFixed の使い方と戻り値が文字列である注意点
・浮動小数点の誤差(1.005 問題)と対策
・Math.floor / Math.ceil / Math.trunc との比較
・負の数での各メソッドの挙動の違い
・Intl.NumberFormat で通貨フォーマット
・金額計算・消費税・表示フォーマットの実務パターン
Math.round で整数に四捨五入する
console.log(Math.round(4.5)); // 5(切り上げ) console.log(Math.round(4.4)); // 4(切り捨て) console.log(Math.round(4.51)); // 5 console.log(Math.round(-4.5)); // -4(0 に近い方) console.log(Math.round(-4.6)); // -5
Math.round は最も近い整数に丸めます。ちょうど 0.5 の場合は正の無限大方向(大きい方)に丸められます。
Math.round(-4.5) は -4(0 に近い方)になります。-5 ではありません。小数第 N 位で四捨五入する
Math.round は整数にしか丸められません。小数第 N 位で丸めるには、10N を掛けてから round し、再度割ります。
function roundTo(num, decimals) {
const factor = 10 ** decimals;
return Math.round(num * factor) / factor;
}
// 小数第1位
console.log(roundTo(3.14159, 1)); // 3.1
// 小数第2位
console.log(roundTo(3.14159, 2)); // 3.14
// 小数第3位
console.log(roundTo(3.14159, 3)); // 3.142
// 整数(小数第0位)
console.log(roundTo(3.14159, 0)); // 3
10の位・100の位で四捨五入する
// 10の位で四捨五入
console.log(Math.round(1234 / 10) * 10); // 1230
// 100の位で四捨五入
console.log(Math.round(1234 / 100) * 100); // 1200
// 汎用関数(負の decimals で大きい桁に対応)
function roundTo(num, decimals) {
const factor = 10 ** decimals;
return Math.round(num * factor) / factor;
}
console.log(roundTo(1234, -1)); // 1230
console.log(roundTo(1234, -2)); // 1200
toFixed で小数桁数を指定する
const num = 3.14159; console.log(num.toFixed(0)); // "3" console.log(num.toFixed(1)); // "3.1" console.log(num.toFixed(2)); // "3.14" console.log(num.toFixed(5)); // "3.14159"
toFixed の注意点
| 注意点 | 説明 |
|---|---|
| 戻り値が文字列 | typeof (3.14).toFixed(1) は "string" |
| 計算に使うと文字列結合になる | (3.14).toFixed(1) + 1 → "3.11"(文字列結合!) |
| 浮動小数点の誤差 | (1.005).toFixed(2) → "1.00"(期待値は “1.01”) |
const str = (3.14159).toFixed(2); // "3.14"(文字列) // 数値に変換 const num1 = Number(str); // 3.14 const num2 = parseFloat(str); // 3.14 const num3 = +str; // 3.14(単項+演算子)
toFixed は表示用のフォーマットメソッドです。計算に使う場合は必ず Number() で数値に変換してください。浮動小数点の誤差(1.005 問題)
1.005 を小数第 2 位で四捨五入すると 1.01 になるはずですが、JavaScript では 1.00 になります。
// 期待値: 1.01 だが.... console.log(Math.round(1.005 * 100) / 100); // 1(= 1.00) console.log((1.005).toFixed(2)); // "1.00" // 原因: 1.005 * 100 が 100.49999... になる console.log(1.005 * 100); // 100.49999999999999
対策: Number.EPSILON を加算する
function roundFixed(num, decimals) {
const factor = 10 ** decimals;
return Math.round((num + Number.EPSILON) * factor) / factor;
}
console.log(roundFixed(1.005, 2)); // 1.01(正しい)
console.log(roundFixed(2.675, 2)); // 2.68(正しい)
console.log(roundFixed(3.14159, 2)); // 3.14
Number.EPSILON(約 2.22 × 10-16)は浮動小数点数で表現可能な最小の差分です。これを加算することで、100.4999... が 100.5 に補正されます。対策: 文字列ベースで計算する(厳密版)
function roundPrecise(num, decimals) {
return Number(
Math.round(parseFloat(num + "e" + decimals)) + "e-" + decimals
);
}
console.log(roundPrecise(1.005, 2)); // 1.01
console.log(roundPrecise(2.675, 2)); // 2.68
指数表記("1.005e2" → 100.5)を使うことで、浮動小数点の乗算誤差を回避しています。
Math.round / Math.floor / Math.ceil / Math.trunc の比較
| メソッド | 動作 | 3.7 | 3.2 | -3.7 | -3.2 |
|---|---|---|---|---|---|
Math.round |
四捨五入 | 4 | 3 | -4 | -3 |
Math.floor |
切り捨て(小さい方向) | 3 | 3 | -4 | -4 |
Math.ceil |
切り上げ(大きい方向) | 4 | 4 | -3 | -3 |
Math.trunc |
小数部除去(0方向) | 3 | 3 | -3 | -3 |
Math.floor と Math.trunc は同じ結果ですが、負の数で異なります。Math.floor(-3.2) は -4、Math.trunc(-3.2) は -3 です。小数桁数を指定した切り捨て・切り上げ
// 小数第2位で切り捨て
function floorTo(num, decimals) {
const factor = 10 ** decimals;
return Math.floor(num * factor) / factor;
}
console.log(floorTo(3.149, 2)); // 3.14
// 小数第2位で切り上げ
function ceilTo(num, decimals) {
const factor = 10 ** decimals;
return Math.ceil(num * factor) / factor;
}
console.log(ceilTo(3.141, 2)); // 3.15
Intl.NumberFormat で通貨フォーマットする
四捨五入した数値を「¥1,234」「$12.99」のような通貨形式で表示するには Intl.NumberFormat が便利です。
// 日本円(小数なし)
const jpyFmt = new Intl.NumberFormat("ja-JP", {
style: "currency", currency: "JPY"
});
console.log(jpyFmt.format(1234567)); // "¥1,234,567"
// USドル(小数2桁)
const usdFmt = new Intl.NumberFormat("en-US", {
style: "currency", currency: "USD"
});
console.log(usdFmt.format(1234.567)); // "$1,234.57"(自動で四捨五入)
// カンマ区切り(通貨記号なし)
const numFmt = new Intl.NumberFormat("ja-JP");
console.log(numFmt.format(1234567)); // "1,234,567"
実務でよく使うパターン
消費税込み金額の計算
function calcTaxIncluded(price, taxRate = 0.10) {
return Math.round(price * (1 + taxRate));
}
console.log(calcTaxIncluded(980)); // 1078
console.log(calcTaxIncluded(1500)); // 1650
console.log(calcTaxIncluded(299)); // 329
パーセンテージの表示
function formatPercent(value, total, decimals = 1) {
if (total === 0) return "0%";
const pct = (value / total) * 100;
return roundFixed(pct, decimals) + "%";
}
console.log(formatPercent(3, 7)); // "42.9%"
console.log(formatPercent(15, 20)); // "75%"
小数点以下を指定桁で表示(桁揃え)
// 価格表示: 常に小数2桁
function formatPrice(price) {
return price.toFixed(2);
}
console.log(formatPrice(12)); // "12.00"
console.log(formatPrice(12.5)); // "12.50"
console.log(formatPrice(12.999)); // "13.00"
関連記事
- 計算と Math オブジェクトの使い方 — 算術演算子・乱数・べき乗
- 四則演算と計算の基本
- input に入力された数値の計算結果をリアルタイム表示する方法
- Intl API を使った日付・数値の国際化フォーマット
- 文字列の長さを取得する方法 — length プロパティ
よくある質問
Math.round() は数値を返し、整数への丸めのみです。toFixed(n) は小数桁数を指定でき文字列を返します。計算には Math.round、表示フォーマットには toFixed と使い分けましょう。1.005 が実際には 1.00499999... として保持されるためです。Number.EPSILON を加算するか、指数表記("1.005e2")を使った計算で回避できます。Math.round(-4.5) は -4(0 に近い方)です。-5 ではありません。切り捨て(Math.floor)は -5 になります。負の数では round / floor / ceil / trunc すべて結果が異なるため、どの方向に丸めたいかを明確にしてください。toFixed は「小数第 N 位まで表示する」ためのフォーマットメソッドで、"12.50" のように末尾のゼロを保持する必要があるため文字列を返します。数値の 12.5 では末尾のゼロを表現できません。Math.round(num / 10) * 10 で 10 の位、Math.round(num / 100) * 100 で 100 の位の四捨五入ができます。汎用的には roundTo(num, -1) のように負の decimals を使う方法もあります。まとめ
JavaScript で四捨五入する方法を整理しました。
- 整数への四捨五入:
Math.round(num) - 小数 N 桁:
Math.round(num * 10**n) / 10**n - 表示フォーマット:
num.toFixed(n)(文字列を返す点に注意) - 浮動小数点誤差: Number.EPSILON 加算 or 指数表記で対策
- 切り捨て / 切り上げ: Math.floor / Math.ceil(負の数での挙動に注意)
- 通貨フォーマット:
Intl.NumberFormatで自動丸め + カンマ区切り
金額計算では整数(円単位)で処理し Math.round で丸めるのが安全です。表示のフォーマットには toFixed や Intl.NumberFormat を使い分けてください。