【JavaScript】数値の端数処理(四捨五入・切り捨て・切り上げ)を正確に制御する実装パターン

目次

概要

数値計算において、小数を整数に丸める処理は頻繁に発生します。

JavaScriptの Math オブジェクトには、一般的な四捨五入だけでなく、特定のビジネスルール(常に切り上げ、0方向への切り捨てなど)に対応するための4つのメソッドが用意されています。

本記事では、これらのメソッドの挙動の違いを明確にし、正の数・負の数それぞれにおける計算結果を制御する方法を解説します。

仕様(入出力)

  • 入力: 任意の浮動小数点数(正の数および負の数)
  • 出力:
    1. 各メソッド(round, floor, ceil, trunc)による演算結果
    2. 結果の画面表示およびコンソール出力

基本の使い方

端数処理を行う各メソッドの挙動は以下の通りです。

メソッド意味挙動の説明戻り値の例 (3.5)戻り値の例 (-3.5)
Math.round()四捨五入最も近い整数にする(.5は正の無限大方向へ)4-3
Math.floor()切り捨て指定された値 以下 の最大の整数を返す3-4
Math.ceil()切り上げ指定された値 以上 の最小の整数を返す4-3
Math.trunc()整数部小数点以下を単純に削除する(0方向へ丸める)3-3

コード全文(HTML / JavaScript)

HTML (index.html)

計算結果を視覚的に比較するためのテーブルレイアウトです。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>端数処理メソッドの比較</title>
    <style>
        body { font-family: sans-serif; padding: 20px; }
        table { border-collapse: collapse; width: 100%; max-width: 800px; margin-top: 20px; }
        th, td { border: 1px solid #ddd; padding: 12px; text-align: center; }
        th { background-color: #f4f4f4; }
        .negative { color: #d32f2f; font-weight: bold; }
    </style>
    <script src="math-rounding.js" defer></script>
</head>
<body>
    <div class="container">
        <h1>数値丸め処理の結果一覧</h1>
        <table>
            <thead>
                <tr>
                    <th>入力値</th>
                    <th>round (四捨五入)</th>
                    <th>floor (切り捨て)</th>
                    <th>ceil (切り上げ)</th>
                    <th>trunc (0方向へ)</th>
                </tr>
            </thead>
            <tbody id="calc-results">
                </tbody>
        </table>
    </div>
</body>
</html>

JavaScript (math-rounding.js)

配送システムの荷物重量計算や、気温データ処理などを想定し、異なる特性を持つ数値で検証を行います。

/**
 * 数値を受け取り、4種類の丸め処理を行ってテーブルに追加する関数
 * @param {number} value - 処理対象の数値
 */
const addResultRow = (value) => {
    // 各メソッドによる計算実行
    const rounded = Math.round(value);
    const floored = Math.floor(value);
    const ceiled  = Math.ceil(value);
    const trunced = Math.trunc(value);

    // 負の数の場合に見やすくクラスを付与
    const valueClass = value < 0 ? 'negative' : '';

    // テーブル行のHTML生成
    const rowHtml = `
        <tr class="${valueClass}">
            <td>${value}</td>
            <td>${rounded}</td>
            <td>${floored}</td>
            <td>${ceiled}</td>
            <td>${trunced}</td>
        </tr>
    `;

    // DOMへの反映
    const tableBody = document.querySelector("#calc-results");
    if (tableBody) {
        tableBody.insertAdjacentHTML('beforeend', rowHtml);
    }
    
    // コンソールでも値を確認
    console.log(`Input: ${value} -> R:${rounded}, F:${floored}, C:${ceiled}, T:${trunced}`);
};

// 1. 通常の正の数(小数部が0.5未満)
// 例: 商品重量 12.3kg
addResultRow(12.34);

// 2. 通常の正の数(小数部が0.5以上)
// 例: 気温 25.8度
addResultRow(25.8);

// 3. 負の数(小数部が-0.5より0に近い)
// 例: 座標調整 -5.2
addResultRow(-5.2);

// 4. 負の数(小数部が-0.5よりマイナス側)
// 例: 割引額計算 -99.9
// ※ ここでの floor と trunc の違いに注目してください
addResultRow(-99.9);

// 5. 境界値(0.5ジャスト)
// Math.roundの「正の無限大方向への丸め」を確認
addResultRow(1.5);
addResultRow(-1.5);

カスタムポイント

  • 小数点以下の桁数指定:Math.round 等は整数への丸めしか行いません。「小数第1位まで残して四捨五入」したい場合は、Math.round(値 * 10) / 10 のように、桁数分だけ10の倍数を掛けてから丸め、再度割るロジックを関数化すると便利です。
  • 表示用フォーマット:計算だけでなく、ユーザーへの表示が目的であれば toFixed(桁数) メソッドや Intl.NumberFormat を使用する方が適切な場合があります。

注意点

優先的に注意すべきは負の数を扱う際の Math.floor() の挙動です。これは「値が小さくなる方向」へ丸めるため、-5.8-5 ではなく -6 になります。直感的な「数値の切り捨て(整数部だけ残す)」を行いたい場合は、ES6で追加された Math.trunc() を使用するか、ビット演算を利用する必要があります。また、Math.round()-1.5-1 に丸める(正の方向へ寄せる)という仕様があり、一般的な「五捨五入」とは異なる場合がある点にも留意が必要です。

応用

指定桁数での四捨五入ヘルパー関数

金額計算などで頻出する、任意の桁数で丸める関数です。

/**
 * 任意の桁数で四捨五入を行う関数
 * @param {number} val - 対象数値
 * @param {number} precision - 残したい小数点以下の桁数
 * @returns {number} 丸められた数値
 */
const roundAt = (val, precision) => {
    const digit = Math.pow(10, precision);
    return Math.round(val * digit) / digit;
};

console.log(roundAt(1.2345, 2)); // 1.23
console.log(roundAt(1.2355, 2)); // 1.24

まとめ

端数処理を行う際は、正の数だけでなく負の数になった時の挙動を正しく理解してメソッドを選択する必要があります。単に「四捨五入したい」場合は Math.round を、ページネーションのページ数計算など「切り上げ」が必要なら Math.ceil を、そしてマイナスを含む座標計算などで「0方向への切り捨て」が必要な場合は Math.trunc を採用することで、計算誤差やロジックの不整合を防ぐことができます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次