業務・実務で使える JavaScript ユーティリティ:数値を小数点以下指定桁数にする方法
JavaScriptで数値を小数点以下指定桁数にしたい場面は、業務でも非常によくあります。金額の表示、税率や割引率の計算結果、平均値、割合、重量、単価、温度、レポート出力、CSV作成など、小数の見せ方をそろえたい場面は多いからです。
ただし、最初に理解しておきたいのは、「小数点以下指定桁数にする」と言っても、やりたいことは1つではないということです。表示だけを整えたいのか、計算に使う数値そのものを丸めたいのかで、使う方法は変わります。
さらに、toFixed() は文字列を返すこと、浮動小数点誤差の影響、負の数の丸め、入力が文字列のときの扱い、末尾の0を残すかどうかなど、初心者がつまずきやすい点も多いです。この記事では、まず考え方を整理し、そのうえで実務で再利用しやすい関数を段階的に作っていきます。
最初に整理する:「小数点以下指定桁数にする」には2つの目的がある
実務で混乱しやすい原因は、「桁数をそろえる」という言葉の中に、別の目的が混ざっていることです。まずは次の2つを分けて考えることが重要です。
- 表示用に、小数点以下の桁数をそろえたい。
- 計算用に、数値そのものを指定桁数で丸めたい。
たとえば、1.2 を「画面で2桁表示したい」なら、1.20 という見た目が必要です。この場合は文字列として整える考え方になります。
一方で、1.2345 を「小数第2位までの数値として次の計算へ渡したい」なら、結果として 1.23 や 1.24 のような number 型がほしいことがあります。
つまり、表示の整形と、計算用の丸めは別の処理として考えることが大切です。
ステップ1:toFixed() の基本を理解する
小数点以下の表示桁数をそろえるなら toFixed()
JavaScriptで最もよく使われるのが toFixed() です。小数点以下を指定した桁数で丸め、必要なら末尾に 0 を補って、文字列として返します。
// 小数点以下2桁で文字列に整形する
console.log((1.234).toFixed(2)); // "1.23"
console.log((1.2).toFixed(2)); // "1.20"
console.log((1).toFixed(2)); // "1.00"
JavaScriptこのように、toFixed(2) は「必ず小数点以下2桁の見た目にする」ため、表やレポート、CSVの表示用データを作るときに便利です。
toFixed() が返すのは number ではなく string
ここが最初の重要ポイントです。toFixed() の戻り値は数値ではなく文字列です。
// 戻り値の型を確認する
const result = (1.23).toFixed(2);
console.log(result); // "1.23"
console.log(typeof result); // "string"JavaScriptそのため、toFixed() の結果をそのまま次の計算に使うと、意図しない文字列連結が起こることがあります。
// 文字列のまま足すと連結になることがある
const price = (1.2).toFixed(2);
console.log(price + 1); // "1.201"JavaScript表示用なら toFixed()、計算用なら number 型へ戻すか、別の方法で丸めると覚えると整理しやすくなります。
ステップ2:まずは数値として安全に扱えるか確認する
実務では、フォームやCSV、APIなどから文字列で値が来ることがよくあります。そのため、桁数をそろえる前に、まず安全に数値へ変換できるかを確認する必要があります。
有限の数値へ変換する関数を用意する
/**
* 入力値を有限の数値へ変換します。
*
* @param {unknown} value 入力値
* @returns {number | null} 正常なら number、失敗なら null
*/
function toFiniteNumber(value) {
// すでに数値型なら、そのまま有限数か確認する
if (typeof value === "number") {
return Number.isFinite(value) ? value : null;
}
// 文字列なら前後の空白を除去してから変換する
if (typeof value === "string") {
const trimmed = value.trim();
// 空文字は未入力として扱う
if (trimmed === "") {
return null;
}
const converted = Number(trimmed);
// NaN や Infinity は不正
return Number.isFinite(converted) ? converted : null;
}
// それ以外の型は不正
return null;
}
console.log(toFiniteNumber("12.345")); // 12.345
console.log(toFiniteNumber("")); // null
console.log(toFiniteNumber("abc")); // null
console.log(toFiniteNumber(Infinity)); // nullJavaScriptこのように、変換と桁数調整を分けておくと、どの段階で不正値が混ざったかを追いやすくなります。
空文字や空白だけは 0 になる落とし穴がある
Number() は、空文字や空白だけの文字列を 0 にしてしまいます。
// Number() は未入力を 0 にしてしまうことがある
console.log(Number("")); // 0
console.log(Number(" ")); // 0
JavaScriptこれをそのまま許してしまうと、未入力が「0.00」として表示されたり、集計へ混ざったりします。業務での入力処理では、変換前に空文字を除外する設計が重要です。
ステップ3:表示用に桁数をそろえる方法を作る
まずは、もっともよく使う「表示用の整形」から作ります。これは文字列を返す関数として設計するとわかりやすいです。
/**
* 数値を小数点以下指定桁数の文字列へ整形します。
*
* @param {unknown} value 入力値
* @param {number} digits 小数点以下の桁数
* @returns {string | null} 正常なら整形済み文字列、失敗なら null
*/
function formatFixed(value, digits = 2) {
// 桁数は 0 以上の整数である必要がある
if (!Number.isInteger(digits) || digits < 0) {
throw new TypeError("digits は0以上の整数で指定してください");
}
// まず有限数へ変換する
const number = toFiniteNumber(value);
// 数値として不正なら null
if (number === null) {
return null;
}
// toFixed() で表示用文字列へ整形する
return number.toFixed(digits);
}
console.log(formatFixed(1.2345, 2)); // "1.23"
console.log(formatFixed(1.2, 2)); // "1.20"
console.log(formatFixed("12.345", 1)); // "12.3"
console.log(formatFixed("abc", 2)); // nullJavaScriptこの関数は、表や帳票、ダウンロード用CSVなど、「見た目をそろえる」用途で使いやすいです。
末尾の0をそろえたいなら文字列で持つ
1.20 という見た目を保ちたいなら、戻り値は文字列のまま扱う必要があります。number 型へ戻すと、末尾の 0 という表示情報は失われます。
// 文字列なら "1.20" を維持できる
const formatted = formatFixed(1.2, 2);
console.log(formatted); // "1.20"
// 数値へ戻すと見た目の 0 は消える
const numeric = Number(formatted);
console.log(numeric); // 1.2JavaScript「桁数をそろえる」のが目的なら、表示用データは文字列として扱うほうが自然です。
ステップ4:計算用に数値そのものを丸める方法を作る
次に、「次の計算へ渡すために、数値そのものを小数点以下指定桁数へ丸めたい」場合を考えます。この場合は、number 型で返す関数が必要です。
toFixed() してから Number() へ戻す方法
もっとも簡単でわかりやすい方法の1つは、toFixed() の結果を Number() で数値へ戻すことです。
/**
* 数値を小数点以下指定桁数へ丸めて number で返します。
*
* @param {unknown} value 入力値
* @param {number} digits 小数点以下の桁数
* @returns {number | null} 正常なら丸めた数値、失敗なら null
*/
function roundToDecimal(value, digits = 2) {
// 桁数の型を確認する
if (!Number.isInteger(digits) || digits < 0) {
throw new TypeError("digits は0以上の整数で指定してください");
}
// まず有限数へ変換する
const number = toFiniteNumber(value);
// 不正なら null
if (number === null) {
return null;
}
// 文字列で丸めてから数値へ戻す
return Number(number.toFixed(digits));
}
console.log(roundToDecimal(1.2345, 2)); // 1.23
console.log(roundToDecimal(1.2, 2)); // 1.2
console.log(roundToDecimal("3.456", 1)); // 3.5
console.log(roundToDecimal("abc", 2)); // nullJavaScriptこの方法は理解しやすいですが、戻り値が number になるため、見た目の桁数は保持されません。つまり 1.20 は 1.2 になります。
表示の桁数と、内部の数値は分けて考える
ここが非常に重要です。1.2 と 1.20 は、数値としては同じです。末尾の 0 は、表示の情報であり、数値そのものの違いではありません。
そのため、「画面に2桁表示したい」のか、「数値として丸めたい」のかを混同しないことが大切です。
ステップ5:浮動小数点誤差に注意する
JavaScriptの number 型は、2進浮動小数点で表現されます。そのため、一見きれいに見える小数でも、内部では誤差を含むことがあります。
// 浮動小数点の代表的な誤差
console.log(0.1 + 0.2); // 0.30000000000000004
JavaScriptこの誤差は、桁数調整でも影響することがあります。特に有名なのが、1.005 を小数第2位にしたいケースです。
// 期待とずれることがある例
console.log((1.005).toFixed(2)); // "1.00" になることがある
JavaScriptこれは初心者にとって非常にわかりにくい部分です。見た目では 1.005 でも、内部表現では少し小さい値になっているため、四捨五入の境界をまたげないことがあります。
誤差を意識した簡易的な丸め関数
実務では、簡易的な対策として Number.EPSILON を加えてから丸める方法が使われることがあります。
/**
* 浮動小数点誤差を少し考慮して小数点以下指定桁数へ丸めます。
*
* @param {unknown} value 入力値
* @param {number} digits 小数点以下の桁数
* @returns {number | null} 正常なら丸めた数値、失敗なら null
*/
function roundToDecimalSafe(value, digits = 2) {
// 桁数チェック
if (!Number.isInteger(digits) || digits < 0) {
throw new TypeError("digits は0以上の整数で指定してください");
}
const number = toFiniteNumber(value);
if (number === null) {
return null;
}
// 10のdigits乗を使って整数丸めへ持ち込む
const factor = 10 ** digits;
// EPSILON を加えて誤差を少し補正する
return Math.round((number + Number.EPSILON) * factor) / factor;
}
console.log(roundToDecimalSafe(1.005, 2)); // 1.01
console.log(roundToDecimalSafe(2.675, 2)); // 2.68JavaScriptただし、これは万能ではありません。すべての小数誤差を完全に解決するわけではないため、金融や税計算のように厳密性が高い処理では、業務ルールに合った設計や専用ライブラリーの検討が必要です。
業務で使える完成版テンプレート:表示用と計算用を分ける
実務では、表示用と計算用を分けて関数を用意すると保守しやすくなります。次の2つを基本セットとして持っておくと使いやすいです。
/**
* 数値を表示用に小数点以下指定桁数の文字列へ整形します。
*
* @param {unknown} value 入力値
* @param {number} digits 小数点以下の桁数
* @returns {string | null} 正常なら文字列、失敗なら null
*/
function formatDecimal(value, digits = 2) {
// 桁数チェック
if (!Number.isInteger(digits) || digits < 0) {
throw new TypeError("digits は0以上の整数で指定してください");
}
const number = toFiniteNumber(value);
if (number === null) {
return null;
}
// 表示用なので文字列のまま返す
return number.toFixed(digits);
}
/**
* 数値を計算用に小数点以下指定桁数へ丸めます。
*
* @param {unknown} value 入力値
* @param {number} digits 小数点以下の桁数
* @returns {number | null} 正常なら数値、失敗なら null
*/
function roundDecimal(value, digits = 2) {
// 桁数チェック
if (!Number.isInteger(digits) || digits < 0) {
throw new TypeError("digits は0以上の整数で指定してください");
}
const number = toFiniteNumber(value);
if (number === null) {
return null;
}
const factor = 10 ** digits;
// 誤差を少し考慮してから丸める
return Math.round((number + Number.EPSILON) * factor) / factor;
}
console.log(formatDecimal(1.2, 2)); // "1.20"
console.log(formatDecimal("3.456", 1)); // "3.5"
console.log(roundDecimal(1.2, 2)); // 1.2
console.log(roundDecimal("3.456", 1)); // 3.5JavaScriptこの設計の利点は、用途が明確になることです。表示用は文字列、計算用は数値、と最初から決めておくと、後で混乱しにくくなります。
初心者が間違えやすいポイントを深掘りする
toFixed() の結果をそのまま足し算しない
toFixed() の戻り値は文字列です。そのため、数値演算のつもりで + を使うと、文字列連結になることがあります。
// 文字列連結になる例
const a = (1.2).toFixed(2); // "1.20"
const b = (2.3).toFixed(2); // "2.30"
console.log(a + b); // "1.202.30"JavaScript計算に使うなら、最初から number で返す関数を使うか、必要に応じて Number() で戻します。
digits は整数で管理する
桁数を表す引数は、0以上の整数として扱うべきです。1.5 桁のような指定は意味を持ちません。
// 桁数が不正な例
console.log(Number.isInteger(2)); // true
console.log(Number.isInteger(2.5)); // false
JavaScript関数の中でチェックしておくことで、呼び出し側のミスを早く見つけられます。
末尾の0を残したいかどうかを最初に決める
たとえば金額表示なら 100.00 のように 0 を残したいことがあります。一方、計算結果の内部値としては 100 や 100.0 と区別する意味はありません。
この違いを曖昧にすると、表示用なのに数値へ戻してしまったり、計算用なのに文字列のまま扱ってしまったりします。関数名や返り値の型で意図を明確にすることが大切です。
指数表記や非常に大きい値にも注意する
非常に大きい数や非常に小さい数では、通常の小数表示ではなく指数表記が関係することがあります。また、桁数の指定が大きすぎると、表示や処理が不自然になる場合があります。
一般的な業務では、小数桁数を 0〜4 程度に制限することが多いです。無制限に指定できる設計にするより、用途に合わせた上限を設けるほうが安全な場合があります。
実務でよくある用途別の例
金額や単価の表示を2桁でそろえる
/**
* 金額表示用に小数点以下2桁へ整形します。
*
* @param {unknown} value 入力値
* @returns {string | null} 正常なら表示用文字列、失敗なら null
*/
function formatPrice(value) {
return formatDecimal(value, 2);
}
console.log(formatPrice(1200)); // "1200.00"
console.log(formatPrice("99.9")); // "99.90"JavaScript割合を小数第1位までの数値へ丸める
/**
* 割合を計算用に小数第1位まで丸めます。
*
* @param {unknown} value 入力値
* @returns {number | null} 正常なら丸めた数値、失敗なら null
*/
function roundRatio(value) {
return roundDecimal(value, 1);
}
console.log(roundRatio(12.34)); // 12.3
console.log(roundRatio("56.78")); // 56.8JavaScript平均点を表示用に1桁でそろえる
/**
* 平均点を表示用に小数第1位で整形します。
*
* @param {unknown} value 入力値
* @returns {string | null} 正常なら表示用文字列、失敗なら null
*/
function formatAverage(value) {
return formatDecimal(value, 1);
}
console.log(formatAverage(82)); // "82.0"
console.log(formatAverage(82.36)); // "82.4"JavaScriptこのように、「表示用」「計算用」「用途別の意味」を関数名に含めると、コードを読む側が意図を理解しやすくなります。
テストで正常系と境界条件を確認する
小数桁数の調整は短いコードでも、境界条件が多いです。通常の値だけでなく、空文字、不正入力、0桁、負の数、誤差が出やすい小数を確認します。
// formatDecimal() のテスト例
const formatCases = [
[1.2345, 2, "1.23"],
[1.2, 2, "1.20"],
[1, 2, "1.00"],
[-1.234, 2, "-1.23"],
["12.345", 1, "12.3"],
["", 2, null],
[" ", 2, null],
["abc", 2, null]
];
for (const [input, digits, expected] of formatCases) {
const actual = formatDecimal(input, digits);
console.log({
input,
digits,
expected,
actual,
pass: actual === expected
});
}JavaScript// roundDecimal() のテスト例
const roundCases = [
[1.2345, 2, 1.23],
[1.235, 2, 1.24],
[1.2, 2, 1.2],
[-1.234, 2, -1.23],
[1.005, 2, 1.01],
["12.345", 1, 12.3],
["", 2, null],
["abc", 2, null]
];
for (const [input, digits, expected] of roundCases) {
const actual = roundDecimal(input, digits);
console.log({
input,
digits,
expected,
actual,
pass: Object.is(actual, expected)
});
}JavaScript特に 1.005 や 2.675 のような値は、浮動小数点誤差の影響を確認するテストとして役立ちます。金額や税率の処理では、実データに近い値でも追加テストを行うと安心です。
まとめ
JavaScriptで数値を小数点以下指定桁数にするときは、まず「表示を整えたいのか」「計算用の数値を丸めたいのか」を分けて考えることが大切です。この違いを整理するだけで、実装ミスを大きく減らせます。
- 表示用に桁数をそろえるなら、
toFixed()を使います。 toFixed()の戻り値は文字列です。- 計算用に丸めたいなら、number 型で返す関数を別に用意します。
- 入力が文字列の場合は、空文字を除外してから数値変換します。
- 浮動小数点誤差の影響を受けるため、境界値のテストが重要です。
- 末尾の0を残したいかどうかで、文字列で持つか数値で持つかを決めます。
実務で本当に重要なのは、単に桁数をそろえることではなく、「どの目的で」「どの型で」「どの丸めルールで」扱うかを明確にすることです。表示用関数と計算用関数を分け、入力変換やテストもあわせて整えることで、保守しやすく安心して再利用できるコードになります。

