JavaScript | 数値を固定小数点数形式で文字列に変換(toFixed() メソッド)

javascrpit JavaScript
スポンサーリンク

toFixed の「丸め誤差」や「正しい対処法」を体験的に比較できるサンプルコードを紹介します。
CodePen やブラウザのコンソールでそのまま動かせます。

サンプル1:toFixed() の丸め誤差を観察する

<h2>toFixed() の丸め誤差を観察</h2>
<pre id="output"></pre>

<script>
const nums = [1.005, 0.615, 2.675, 10.235];
let result = "";

for (const n of nums) {
  const fixed = n.toFixed(2);
  result += `元の値: ${n}\n toFixed(2): ${fixed}\n\n`;
}

document.getElementById("output").textContent = result;
</script>
HTML

🔍 解説

  • 1.0050.615 は内部的に「少し小さい」数値(例:1.00499999…)になり、
    toFixed(2) では "1.00""0.61" になることがあります。
  • これが 浮動小数点誤差 の典型例です。

サンプル2:Number.EPSILON を使って補正した安全版丸め

<h2>Number.EPSILON を使った安全な丸め</h2>
<pre id="output2"></pre>

<script>
function safeRound(num, digits = 2) {
  const factor = 10 ** digits;
  return Math.round((num + Number.EPSILON) * factor) / factor;
}

const nums = [1.005, 0.615, 2.675, 10.235];
let result2 = "";

for (const n of nums) {
  const fixed = n.toFixed(2);
  const safe = safeRound(n, 2).toFixed(2);
  result2 += `元の値: ${n}\n toFixed(2): ${fixed}\n safeRound: ${safe}\n\n`;
}

document.getElementById("output2").textContent = result2;
</script>
HTML

🔍 ポイント

  • safeRound() は内部誤差を補うために Number.EPSILON を加算。
  • 多くのケースで "1.01" のように人間が期待する四捨五入結果になります。

サンプル3:表示目的なら Intl.NumberFormat を使う

<h2>Intl.NumberFormat で丸めを制御(推奨:表示用)</h2>
<pre id="output3"></pre>

<script>
const formatter = new Intl.NumberFormat('ja-JP', {
  minimumFractionDigits: 2,
  maximumFractionDigits: 2
});

const nums = [1.005, 0.615, 2.675, 10.235];
let result3 = "";

for (const n of nums) {
  const formatted = formatter.format(n);
  result3 += `元の値: ${n}\n Intl.NumberFormat: ${formatted}\n\n`;
}

document.getElementById("output3").textContent = result3;
</script>
HTML

🔍 ポイント

  • Intl.NumberFormat は国ごとのフォーマットや丸め規則を考慮。
  • 表示専用としては最も安定・信頼できる方法です。

サンプル4(おまけ):CodePen風 UI デモ

リアルタイムで入力して試したい方は下記の HTML を CodePen に貼り付けてみてください:

<h2>toFixed 丸め誤差デモ</h2>
<input type="number" id="num" value="1.005" step="0.001">
<input type="number" id="digits" value="2" min="0" max="10">
<button id="run">実行</button>

<pre id="out"></pre>

<script>
function safeRound(num, digits = 2) {
  const factor = 10 ** digits;
  return Math.round((num + Number.EPSILON) * factor) / factor;
}

document.getElementById("run").addEventListener("click", () => {
  const n = parseFloat(document.getElementById("num").value);
  const d = parseInt(document.getElementById("digits").value);

  const toFixed = n.toFixed(d);
  const safe = safeRound(n, d).toFixed(d);
  const intl = new Intl.NumberFormat('ja-JP', {
    minimumFractionDigits: d,
    maximumFractionDigits: d
  }).format(n);

  document.getElementById("out").textContent =
    `入力値: ${n}\n桁数: ${d}\n\n` +
    `toFixed → ${toFixed}\n` +
    `safeRound → ${safe}\n` +
    `Intl.NumberFormat → ${intl}`;
});
</script>
HTML

このデモでは:

  • 数値と桁数を入力
  • toFixed / safeRound / Intl.NumberFormat の結果をリアルタイム比較
    ができます。

See the Pen JavaScript toFixed Rounding Error Demo by MONO365 -Color your days- (@monoqlo365) on CodePen.

このデモでできること

機能説明
🌙 ダークモードワンクリックでライト/ダーク切替
🧮 3種類の丸め比較toFixed, safeRound, Intl.NumberFormat の結果を同時表示
💾 履歴保存localStorage に直近10回分を保存/表示
📊 グラフ化Chart.js で結果の数値差をバーグラフ表示
🔁 履歴クリアワンクリックで削除可能
タイトルとURLをコピーしました