【JavaScript】四捨五入の方法|Math.round・toFixed・小数桁数指定・浮動小数点の誤差対策・切り捨て / 切り上げとの比較まで解説

金額の計算、パーセンテージの表示、センサー値の丸めなど、四捨五入はプログラミングで最も頻繁に行われる数値操作の一つです。JavaScript では Math.round が基本ですが、小数桁数を指定した四捨五入や浮動小数点の誤差対策など、実務で押さえておくべきポイントがあります。

この記事でわかること
・Math.round で整数に四捨五入する基本
・小数第 N 位で四捨五入する方法
・toFixed の使い方と戻り値が文字列である注意点
・浮動小数点の誤差(1.005 問題)と対策
・Math.floor / Math.ceil / Math.trunc との比較
・負の数での各メソッドの挙動の違い
・Intl.NumberFormat で通貨フォーマット
・金額計算・消費税・表示フォーマットの実務パターン
スポンサーリンク

Math.round で整数に四捨五入する

JavaScript
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 の場合は正の無限大方向(大きい方)に丸められます。

負の数の 0.5 に注意してください。Math.round(-4.5)-4(0 に近い方)になります。-5 ではありません。

小数第 N 位で四捨五入する

Math.round は整数にしか丸められません。小数第 N 位で丸めるには、10N を掛けてから round し、再度割ります。

JavaScript
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の位で四捨五入する

JavaScript
// 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 で小数桁数を指定する

JavaScript
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”)
toFixed の戻り値を数値に変換する
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 を加算する

JavaScript
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 に補正されます。

対策: 文字列ベースで計算する(厳密版)

JavaScript
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.floorMath.trunc は同じ結果ですが、負の数で異なりますMath.floor(-3.2)-4Math.trunc(-3.2)-3 です。

小数桁数を指定した切り捨て・切り上げ

JavaScript
// 小数第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 が便利です。

JavaScript
// 日本円(小数なし)
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"

実務でよく使うパターン

消費税込み金額の計算

JavaScript
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

パーセンテージの表示

JavaScript
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%"

小数点以下を指定桁で表示(桁揃え)

JavaScript
// 価格表示: 常に小数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"

関連記事

よくある質問

QMath.round と toFixed の違いは何ですか?
AMath.round()数値を返し、整数への丸めのみです。toFixed(n) は小数桁数を指定でき文字列を返します。計算には Math.round、表示フォーマットには toFixed と使い分けましょう。
Q1.005 を小数第 2 位で四捨五入すると 1.00 になるのはなぜですか?
A浮動小数点の内部表現で 1.005 が実際には 1.00499999... として保持されるためです。Number.EPSILON を加算するか、指数表記("1.005e2")を使った計算で回避できます。
Q負の数の四捨五入で注意すべき点は?
AMath.round(-4.5)-4(0 に近い方)です。-5 ではありません。切り捨て(Math.floor)は -5 になります。負の数では round / floor / ceil / trunc すべて結果が異なるため、どの方向に丸めたいかを明確にしてください。
QtoFixed の戻り値が文字列なのはなぜですか?
AtoFixed は「小数第 N 位まで表示する」ためのフォーマットメソッドで、"12.50" のように末尾のゼロを保持する必要があるため文字列を返します。数値の 12.5 では末尾のゼロを表現できません。
Q10の位や100の位で四捨五入するにはどうすればよいですか?
AMath.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 で丸めるのが安全です。表示のフォーマットには toFixedIntl.NumberFormat を使い分けてください。