C#の小数点処理を完全解説|切り捨て・四捨五入・表示桁数の指定方法
はじめに
C#で小数点を扱う場面は、計算結果の丸め、金額計算、割合表示、測定値の補正、画面表示の桁数調整など非常に多くあります。たとえば「小数点以下を切り捨てたい」「小数点第2位まで表示したい」「四捨五入したはずなのに結果が合わない」といった悩みは、C#の開発でよく発生します。
C#の小数点処理では、主に次のような機能を使います。
切り捨て:
Math.Truncate切り下げ:
Math.Floor切り上げ:
Math.Ceiling四捨五入:
Math.Round表示桁数の指定:
ToString、文字列補間、数値書式指定
ただし、これらは似ているようで役割が異なります。特に、値そのものを変更する処理と、表示だけを整える処理は明確に分けて考える必要があります。
この記事では、C#の小数点処理について、切り捨て・四捨五入・切り上げ・表示桁数の指定方法を、サンプルコード付きでわかりやすく解説します。
1. C#で小数点処理が必要になる場面
1-1. 計算結果の小数点以下を調整したいケース
C#で割り算や平均値の計算を行うと、小数点以下が長く続く結果になることがあります。
C#double average = 10.0 / 3.0;
Console.WriteLine(average);
実行結果の例は次のようになります。
C#3.3333333333333335
このような値をそのまま画面に表示すると、ユーザーにとって見づらくなります。そのため、次のように小数点以下の桁数を調整する処理が必要になります。
C#double average = 10.0 / 3.0;
double rounded = Math.Round(average, 2);
Console.WriteLine(rounded);
C#3.33
計算結果を業務ロジックで使用する場合は値そのものを丸め、画面表示だけ整えたい場合は文字列書式で対応するのが基本です。
1-2. 金額・税率・割合・測定値を扱うケース
C#の小数点処理が特に重要になるのは、次のようなデータを扱う場合です。
| 用途 | 例 | よく使う処理 |
|---|---|---|
| 金額 | 税込価格、割引額、請求金額 | decimal、切り捨て、四捨五入 |
| 税率 | 消費税、手数料率 | decimal、小数点第2位で丸め |
| 割合 | 達成率、進捗率、正答率 | Math.Round、ToString("F2") |
| 測定値 | 重量、距離、温度、速度 | double、表示桁数の指定 |
| 統計値 | 平均、分散、標準偏差 | double、必要に応じた丸め |
たとえば、金額計算では1円未満を切り捨てる、税額を小数点以下で丸める、パーセンテージを小数点第1位まで表示する、といった処理がよく使われます。
C#decimal price = 980m;
decimal taxRate = 0.10m;
decimal tax = price * taxRate;
decimal total = price + tax;
Console.WriteLine(total);
金額や税率のように正確な10進数が求められる処理では、doubleではなくdecimalを使うのが基本です。
1-3. 表示だけ整えたい場合と値そのものを変更したい場合の違い
C#の小数点処理で重要なのが、「値を変更する」のか「表示だけを変更する」のかという違いです。
たとえば、Math.Roundを使うと数値そのものを丸めた新しい値を取得できます。
C#double value = 12.3456;
double rounded = Math.Round(value, 2);
Console.WriteLine(rounded);
C#12.35
一方、ToString("F2")は表示用の文字列を作るだけです。元の数値は変わりません。
C#double value = 12.3456;
string text = value.ToString("F2");
Console.WriteLine(text);
Console.WriteLine(value);
C#12.35
12.3456
つまり、計算結果として丸めた値を後続処理で使いたい場合はMath.Roundなどを使い、画面や帳票に表示するだけならToStringや文字列補間を使います。
1-4. 小数点処理でよく使うメソッド一覧
C#の小数点処理でよく使うメソッドを整理すると、次のようになります。
| メソッド・書式 | 用途 | 例 |
|---|---|---|
Math.Truncate | 小数点以下を0方向に切り捨てる | 3.9 → 3、-3.9 → -3 |
Math.Floor | 指定値以下の最大の整数にする | 3.9 → 3、-3.1 → -4 |
Math.Ceiling | 指定値以上の最小の整数にする | 3.1 → 4、-3.9 → -3 |
Math.Round | 指定桁数で丸める | 3.456 → 3.46 |
ToString("F2") | 小数点以下2桁で表示する | 3.4 → "3.40" |
ToString("N2") | 桁区切り付きで小数点以下2桁表示 | 1234.5 → "1,234.50" |
ToString("0.##") | 必要な小数桁だけ表示 | 3.4 → "3.4" |
Microsoft公式ドキュメントでも、丸め処理にはMath.Ceiling、Math.Floor、Math.Roundを使うことが示されています。Microsoft Learn
2. C#の小数型の基本
2-1. double・float・decimalの違い
C#で小数点を扱う主な型には、double、float、decimalがあります。
| 型 | 特徴 | 主な用途 |
|---|---|---|
float | 単精度浮動小数点数。メモリ使用量が少ない | ゲーム、画像処理、大量データ |
double | 倍精度浮動小数点数。一般的な小数計算でよく使う | 科学技術計算、測定値、統計 |
decimal | 10進数の精度を重視する型 | 金額、税率、会計処理 |
C#では、小数点付きの数値リテラルは、サフィックスを付けない場合はdoubleとして扱われます。floatにはf、decimalにはmを付けます。MicrosoftのC#組み込み型の説明でも、一般的な浮動小数点計算ではdouble、メモリ制約がある場合はfloat、金融計算のように正確な10進精度が必要な場合はdecimalが推奨されています。Microsoft Learn
C#double d = 1.23;
float f = 1.23f;
decimal m = 1.23m;
特に、金額計算で1.23mのようにmを付け忘れると、doubleとして扱われるため注意が必要です。
2-2. 小数点計算で誤差が発生する理由
C#のdoubleやfloatは2進浮動小数点数です。コンピューター内部では2進数で値を表現するため、10進数の小数を正確に表せないことがあります。
たとえば、次のコードを見てください。
C#double result = 0.1 + 0.2;
Console.WriteLine(result);
期待する結果は0.3ですが、実際には次のような値になる場合があります。
C#0.30000000000000004
これはC#だけの問題ではなく、2進浮動小数点数を使う多くのプログラミング言語で発生する性質です。
そのため、doubleを使う場合は、厳密な一致比較や金額計算には注意が必要です。
C#double result = 0.1 + 0.2;
Console.WriteLine(result == 0.3);
C#False
このような場合は、許容誤差を使って比較するか、正確な10進表現が必要ならdecimalを使います。
C#double result = 0.1 + 0.2;
double expected = 0.3;
double tolerance = 0.0000001;
Console.WriteLine(Math.Abs(result - expected) < tolerance);
C#True
2-3. 金額計算ではdecimalを使うべき理由
金額計算では、doubleではなくdecimalを使うのが基本です。
理由は、decimalが10進数の精度を重視した型だからです。消費税、割引率、手数料、請求金額などは10進数で正確に扱う必要があります。
C#decimal price = 1000m;
decimal taxRate = 0.10m;
decimal tax = price * taxRate;
decimal total = price + tax;
Console.WriteLine(total);
C#1100.00
一方、doubleは科学技術計算や測定値など、多少の丸め誤差を許容できる場面に向いています。
C#double distance = 123.456;
double time = 7.89;
double speed = distance / time;
Console.WriteLine(speed);
金額計算では、1円単位の差が問題になることがあります。会計処理や請求処理では、decimalを使ったうえで、どのタイミングで切り捨て・四捨五入・切り上げを行うかを明確にしておきましょう。
2-4. 小数リテラルの書き方
C#では、小数リテラルの末尾にサフィックスを付けることで型を指定できます。
C#double value1 = 12.34;
float value2 = 12.34f;
decimal value3 = 12.34m;
サフィックスを付けない小数はdoubleです。
C#var value = 12.34;
Console.WriteLine(value.GetType());
C#System.Double
decimalに代入する場合は、mを付ける必要があります。
C#decimal price = 12.34m;
次のように書くとコンパイルエラーになります。
C#decimal price = 12.34; // エラー
12.34はdoubleとして扱われるため、decimalに暗黙変換できないからです。金額計算では、必ず100m、0.1m、1.08mのようにmを付けましょう。
3. C#で小数点以下を切り捨てる方法
3-1. Math.Truncateで小数点以下を切り捨てる
C#で小数点以下を単純に削除したい場合は、Math.Truncateを使います。
C#double value = 123.456;
double result = Math.Truncate(value);
Console.WriteLine(result);
C#123
Math.Truncateは、小数点以下を取り除いて整数部分だけを返します。Microsoft公式ドキュメントでは、Math.Truncateは値を0方向に丸めるメソッドと説明されています。Microsoft Learn
C#Console.WriteLine(Math.Truncate(3.9)); // 3
Console.WriteLine(Math.Truncate(3.1)); // 3
Console.WriteLine(Math.Truncate(-3.1)); // -3
Console.WriteLine(Math.Truncate(-3.9)); // -3
「小数点以下を削除する」という意味では、Math.Truncateが最も直感的です。
3-2. Math.Floorとの違い
Math.Truncateと似たメソッドにMath.Floorがあります。
Math.Floorは、指定した値以下の最大の整数を返します。つまり、負の方向に丸める処理です。
C#Console.WriteLine(Math.Floor(3.9)); // 3
Console.WriteLine(Math.Floor(3.1)); // 3
Console.WriteLine(Math.Floor(-3.1)); // -4
Console.WriteLine(Math.Floor(-3.9)); // -4
正の数ではMath.TruncateとMath.Floorの結果は同じになることが多いですが、負の数では結果が変わります。公式ドキュメントでも、Math.Floorは負の無限大方向への丸めとして説明されています。Microsoft Learn
C#double value = -3.14;
Console.WriteLine(Math.Truncate(value)); // -3
Console.WriteLine(Math.Floor(value)); // -4
小数点以下を単純に削除したいならMath.Truncate、必ず指定値以下の整数にしたいならMath.Floorを使います。
3-3. 正の数・負の数で結果が変わる点に注意
C#の小数点処理では、正の数と負の数で結果が変わるメソッドがあります。
特に注意したいのは、Math.Truncate、Math.Floor、Math.Ceilingの違いです。
C#double positive = 3.7;
double negative = -3.7;
Console.WriteLine(Math.Truncate(positive)); // 3
Console.WriteLine(Math.Floor(positive)); // 3
Console.WriteLine(Math.Ceiling(positive)); // 4
Console.WriteLine(Math.Truncate(negative)); // -3
Console.WriteLine(Math.Floor(negative)); // -4
Console.WriteLine(Math.Ceiling(negative)); // -3
表にすると次のようになります。
| 値 | Math.Truncate | Math.Floor | Math.Ceiling |
|---|---|---|---|
3.7 | 3 | 3 | 4 |
-3.7 | -3 | -4 | -3 |
「切り捨て」という言葉だけでMath.Floorを使うと、負の数で意図しない結果になることがあります。負の数を扱う可能性がある場合は、どの方向に丸めるべきかを明確にしましょう。
3-4. 小数点第n位で切り捨てる方法
Math.Truncateは、そのまま使うと整数部分だけを残します。小数点第2位まで残して、それより下を切り捨てたい場合は、10の累乗を使います。
たとえば、小数点第2位まで残す場合は、100倍して切り捨ててから100で割ります。
C#double value = 123.4567;
double result = Math.Truncate(value * 100) / 100;
Console.WriteLine(result);
C#123.45
小数点第1位で切り捨てる場合は10倍、小数点第3位で切り捨てる場合は1000倍します。
C#double value = 123.4567;
Console.WriteLine(Math.Truncate(value * 10) / 10); // 123.4
Console.WriteLine(Math.Truncate(value * 100) / 100); // 123.45
Console.WriteLine(Math.Truncate(value * 1000) / 1000); // 123.456
任意の桁数に対応したい場合は、Math.Powを使います。
C#double TruncateDecimal(double value, int digits)
{
double factor = Math.Pow(10, digits);
return Math.Truncate(value * factor) / factor;
}
Console.WriteLine(TruncateDecimal(123.4567, 2));
C#123.45
3-5. decimal型で切り捨てる場合の書き方
Math.Truncateにはdouble用とdecimal用のオーバーロードがあります。そのため、decimal型でも同じように使えます。
C#decimal value = 123.4567m;
decimal result = Math.Truncate(value);
Console.WriteLine(result);
C#123
小数点第2位で切り捨てる場合は、次のように書けます。
C#decimal value = 123.4567m;
decimal result = Math.Truncate(value * 100m) / 100m;
Console.WriteLine(result);
C#123.45
decimalでは100mのように、計算に使う数値にもmを付けるのがポイントです。
任意の桁数に対応したい場合は、decimal向けに次のようなメソッドを作ると便利です。
C#decimal TruncateDecimal(decimal value, int digits)
{
decimal factor = (decimal)Math.Pow(10, digits);
return Math.Truncate(value * factor) / factor;
}
Console.WriteLine(TruncateDecimal(123.4567m, 2));
C#123.45
金額計算で小数点以下を切り捨てる場合は、decimalとMath.Truncateを組み合わせる方法がよく使われます。
4. C#で小数点以下を四捨五入する方法
4-1. Math.Roundの基本的な使い方
C#で小数点以下を四捨五入したい場合は、Math.Roundを使います。
C#double value = 123.456;
double result = Math.Round(value);
Console.WriteLine(result);
C#123
Math.Round(value)は、最も近い整数に丸めます。
C#Console.WriteLine(Math.Round(123.4)); // 123
Console.WriteLine(Math.Round(123.5)); // 124 または丸め方式に依存
Console.WriteLine(Math.Round(123.6)); // 124
ただし、C#のMath.Roundは、何も指定しない場合に一般的な「5以上なら切り上げ」とは異なる結果になることがあります。これが、C#の小数点処理でつまずきやすいポイントです。
4-2. 小数点第n位で四捨五入する方法
小数点以下の桁数を指定して丸めたい場合は、Math.Roundの第2引数に桁数を指定します。
C#double value = 123.4567;
Console.WriteLine(Math.Round(value, 1)); // 123.5
Console.WriteLine(Math.Round(value, 2)); // 123.46
Console.WriteLine(Math.Round(value, 3)); // 123.457
小数点第2位まで表示したい値を作る場合は、次のように書きます。
C#double value = 123.4567;
double result = Math.Round(value, 2);
Console.WriteLine(result);
C#123.46
Math.Round(value, 2)は「小数点第2位まで残す」処理です。つまり、小数点第3位を見て丸めます。
4-3. Math.Roundの丸め方式に注意
Math.Roundで最も注意すべき点は、既定の丸め方式です。
C#のMath.Roundは、引数によっては中間値を「最も近い偶数」に丸めます。これは「銀行丸め」や「偶数丸め」と呼ばれる方式です。Microsoft公式ドキュメントでも、Round(Double)やRound(Double, Int32)は中間値を最も近い偶数に丸めると説明されています。Microsoft Learn
たとえば、次の結果を見てください。
C#Console.WriteLine(Math.Round(1.5)); // 2
Console.WriteLine(Math.Round(2.5)); // 2
Console.WriteLine(Math.Round(3.5)); // 4
Console.WriteLine(Math.Round(4.5)); // 4
2.5が3ではなく2になるのは、2が偶数だからです。
これはバグではなく、丸め誤差の偏りを減らすための仕様です。しかし、一般的な四捨五入を期待している場合は、意図しない結果に見えることがあります。
4-4. MidpointRounding.AwayFromZeroを使う方法
一般的な「5以上なら切り上げ」に近い四捨五入をしたい場合は、MidpointRounding.AwayFromZeroを指定します。
C#Console.WriteLine(Math.Round(1.5, MidpointRounding.AwayFromZero)); // 2
Console.WriteLine(Math.Round(2.5, MidpointRounding.AwayFromZero)); // 3
Console.WriteLine(Math.Round(3.5, MidpointRounding.AwayFromZero)); // 4
Console.WriteLine(Math.Round(4.5, MidpointRounding.AwayFromZero)); // 5
小数点第2位で一般的な四捨五入をしたい場合は、次のように書きます。
C#double value = 123.455;
double result = Math.Round(value, 2, MidpointRounding.AwayFromZero);
Console.WriteLine(result);
C#123.46
MidpointRounding.AwayFromZeroは、0から遠ざかる方向に丸める方式です。正の数では一般的な四捨五入に近く、負の数では絶対値が大きくなる方向に丸められます。
C#Console.WriteLine(Math.Round(1.5, MidpointRounding.AwayFromZero)); // 2
Console.WriteLine(Math.Round(-1.5, MidpointRounding.AwayFromZero)); // -2
4-5. 銀行丸めと一般的な四捨五入の違い
銀行丸めと一般的な四捨五入の違いを表にすると、次のようになります。
| 値 | 既定のMath.Round | AwayFromZero |
|---|---|---|
1.5 | 2 | 2 |
2.5 | 2 | 3 |
3.5 | 4 | 4 |
4.5 | 4 | 5 |
-1.5 | -2 | -2 |
-2.5 | -2 | -3 |
銀行丸めは、集計時の丸め誤差の偏りを減らす目的で使われます。一方、一般的な業務仕様で「5以上は切り上げ」と決まっている場合は、MidpointRounding.AwayFromZeroを明示する方が安全です。
C#decimal amount = 12.5m;
decimal rounded1 = Math.Round(amount);
decimal rounded2 = Math.Round(amount, MidpointRounding.AwayFromZero);
Console.WriteLine(rounded1); // 12
Console.WriteLine(rounded2); // 13
C#で小数点の四捨五入を実装するときは、仕様書に「銀行丸め」なのか「一般的な四捨五入」なのかを明記しておくとトラブルを防げます。
4-6. decimal型とdouble型でMath.Roundを使う違い
Math.Roundには、double用とdecimal用のオーバーロードがあります。
C#double doubleValue = 123.455;
decimal decimalValue = 123.455m;
Console.WriteLine(Math.Round(doubleValue, 2, MidpointRounding.AwayFromZero));
Console.WriteLine(Math.Round(decimalValue, 2, MidpointRounding.AwayFromZero));
doubleは2進浮動小数点数のため、値によっては内部表現の誤差が丸め結果に影響することがあります。
C#double value = 2.675;
Console.WriteLine(Math.Round(value, 2));
環境や値によって、期待した2.68ではなく2.67のように見えるケースがあります。これは、2.675が内部的に正確な10進数として保持されているとは限らないためです。
金額や税額のように正確な10進の丸めが必要な場合は、decimalを使いましょう。
C#decimal value = 2.675m;
Console.WriteLine(Math.Round(value, 2, MidpointRounding.AwayFromZero));
C#2.68
5. C#で小数点以下を切り上げる方法
5-1. Math.Ceilingで小数点以下を切り上げる
C#で小数点以下を切り上げたい場合は、Math.Ceilingを使います。
C#double value = 123.001;
double result = Math.Ceiling(value);
Console.WriteLine(result);
C#124
Math.Ceilingは、指定した値以上の最小の整数を返します。公式ドキュメントでも、Ceilingは指定した値以上の最小の整数値を返すメソッドとして説明されています。Microsoft Learn
C#Console.WriteLine(Math.Ceiling(3.1)); // 4
Console.WriteLine(Math.Ceiling(3.9)); // 4
Console.WriteLine(Math.Ceiling(3.0)); // 3
少しでも小数点以下があれば上の整数にしたい場合に使います。
5-2. Math.CeilingとMath.Floorの違い
Math.CeilingとMath.Floorは、丸める方向が逆です。
C#double value = 3.14;
Console.WriteLine(Math.Ceiling(value)); // 4
Console.WriteLine(Math.Floor(value)); // 3
| メソッド | 意味 | 例 |
|---|---|---|
Math.Ceiling | 指定値以上の最小整数 | 3.14 → 4 |
Math.Floor | 指定値以下の最大整数 | 3.14 → 3 |
正の数だけを見ると、Ceilingは切り上げ、Floorは切り下げのように見えます。しかし、負の数では直感と異なる場合があります。
C#Console.WriteLine(Math.Ceiling(-3.14)); // -3
Console.WriteLine(Math.Floor(-3.14)); // -4
負の数を扱う場合は、「数直線上でどちらの方向に丸めるか」を意識しましょう。
5-3. 小数点第n位で切り上げる方法
小数点第2位まで残して、それより下を切り上げたい場合は、Math.Ceilingと10の累乗を組み合わせます。
C#double value = 123.451;
double result = Math.Ceiling(value * 100) / 100;
Console.WriteLine(result);
C#123.46
小数点第1位、第2位、第3位で切り上げる例は次のとおりです。
C#double value = 123.4567;
Console.WriteLine(Math.Ceiling(value * 10) / 10); // 123.5
Console.WriteLine(Math.Ceiling(value * 100) / 100); // 123.46
Console.WriteLine(Math.Ceiling(value * 1000) / 1000); // 123.457
任意の桁数に対応する場合は、次のようにメソッド化できます。
C#double CeilingDecimal(double value, int digits)
{
double factor = Math.Pow(10, digits);
return Math.Ceiling(value * factor) / factor;
}
Console.WriteLine(CeilingDecimal(123.4567, 2));
C#123.46
decimalで処理する場合は、次のように書けます。
C#decimal CeilingDecimal(decimal value, int digits)
{
decimal factor = (decimal)Math.Pow(10, digits);
return Math.Ceiling(value * factor) / factor;
}
Console.WriteLine(CeilingDecimal(123.4567m, 2));
C#123.46
5-4. 負の数を切り上げるときの注意点
Math.Ceilingは「小数点以下があれば絶対値を大きくする」処理ではありません。あくまで「指定値以上の最小の整数」にする処理です。
C#Console.WriteLine(Math.Ceiling(3.1)); // 4
Console.WriteLine(Math.Ceiling(-3.1)); // -3
-3.1より大きい整数のうち最小のものは-3なので、結果は-3になります。
「負の数でも絶対値を大きくする方向に切り上げたい」という仕様の場合は、単純にMath.Ceilingを使うだけでは不十分です。
C#double RoundUpAwayFromZero(double value)
{
return value >= 0 ? Math.Ceiling(value) : Math.Floor(value);
}
Console.WriteLine(RoundUpAwayFromZero(3.1)); // 4
Console.WriteLine(RoundUpAwayFromZero(-3.1)); // -4
業務仕様で「切り上げ」と書かれている場合でも、負の値をどう扱うかは必ず確認しましょう。
6. C#で小数点の表示桁数を指定する方法
6-1. ToStringで小数点以下の桁数を指定する
C#で小数点以下の表示桁数を指定したい場合は、ToStringに書式指定文字列を渡します。
C#double value = 123.456;
Console.WriteLine(value.ToString("F2"));
C#123.46
ToString("F2")は、小数点以下2桁の固定小数点形式で表示する指定です。
ただし、これは表示用の文字列を作る処理です。元の数値が変更されるわけではありません。
C#double value = 123.456;
string text = value.ToString("F2");
Console.WriteLine(text); // 123.46
Console.WriteLine(value); // 123.456
6-2. F指定子で固定小数点表示にする
F指定子は、固定小数点形式で数値を表示するための標準数値書式指定子です。
C#double value = 123.4;
Console.WriteLine(value.ToString("F0"));
Console.WriteLine(value.ToString("F1"));
Console.WriteLine(value.ToString("F2"));
Console.WriteLine(value.ToString("F3"));
C#123
123.4
123.40
123.400
F2を指定すると、小数点以下が2桁になるように0埋めされます。
C#double value = 5;
Console.WriteLine(value.ToString("F2"));
C#5.00
価格や割合など、常に同じ桁数で表示したい場合に便利です。
6-3. N指定子で桁区切り付き表示にする
N指定子を使うと、桁区切り付きで数値を表示できます。
C#double value = 1234567.89;
Console.WriteLine(value.ToString("N2"));
C#1,234,567.89
N0、N1、N2のように指定することで、小数点以下の桁数を制御できます。
C#double value = 1234567.89;
Console.WriteLine(value.ToString("N0")); // 1,234,568
Console.WriteLine(value.ToString("N1")); // 1,234,567.9
Console.WriteLine(value.ToString("N2")); // 1,234,567.89
金額や集計値を画面表示する場合は、N2のような書式がよく使われます。
6-4. 0と#を使ったカスタム書式指定
C#では、0と#を使って小数点の表示形式を細かく指定できます。
| 書式 | 意味 | 例 |
|---|---|---|
0.00 | 小数点以下2桁を必ず表示 | 1.2 → 1.20 |
0.## | 小数点以下2桁まで必要な分だけ表示 | 1.2 → 1.2 |
#,0.00 | 桁区切り付きで小数点以下2桁表示 | 1234.5 → 1,234.50 |
0.### | 小数点以下3桁まで表示 | 1.2345 → 1.235 |
サンプルコードは次のとおりです。
C#double value1 = 1.2;
double value2 = 1.2345;
double value3 = 1234.5;
Console.WriteLine(value1.ToString("0.00"));
Console.WriteLine(value1.ToString("0.##"));
Console.WriteLine(value2.ToString("0.###"));
Console.WriteLine(value3.ToString("#,0.00"));
C#1.20
1.2
1.234
1,234.50
0は桁がない場合も0を表示し、#は不要な0を表示しません。
6-5. string interpolationで小数点の表示桁数を指定する
文字列補間を使うと、より読みやすく小数点の表示桁数を指定できます。
C#double value = 123.456;
Console.WriteLine($"{value:F2}");
C#123.46
桁区切り付きで表示する場合は、次のように書きます。
C#decimal amount = 1234567.8m;
Console.WriteLine($"{amount:N2}");
C#1,234,567.80
文章の中に数値を埋め込む場合にも便利です。
C#double rate = 0.8567;
Console.WriteLine($"達成率は{rate * 100:F1}%です。");
C#達成率は85.7%です。
ToStringよりも自然に書けるため、ログ出力や画面表示でよく使われます。
6-6. 表示桁数の指定は値そのものを変更しない点に注意
ToString("F2")や$"{value:F2}"は、あくまで表示用の文字列を作る処理です。
C#double value = 123.456;
Console.WriteLine(value.ToString("F2"));
Console.WriteLine(value);
C#123.46
123.456
このように、表示上は123.46になりますが、変数valueの中身は123.456のままです。
後続の計算でも丸めた値を使いたい場合は、Math.Roundなどで別の変数に代入します。
C#double value = 123.456;
double rounded = Math.Round(value, 2);
Console.WriteLine(rounded);
C#123.46
画面表示だけならToString、値そのものを丸めるならMath.Roundと覚えておきましょう。
7. 小数点第n位で処理する実装パターン
7-1. 小数点第1位で丸める方法
小数点第1位まで残したい場合は、Math.Round(value, 1)を使います。
C#double value = 12.345;
double result = Math.Round(value, 1);
Console.WriteLine(result);
C#12.3
一般的な四捨五入に近い処理にしたい場合は、MidpointRounding.AwayFromZeroを指定します。
C#double value = 12.35;
double result = Math.Round(value, 1, MidpointRounding.AwayFromZero);
Console.WriteLine(result);
C#12.4
小数点第1位まで表示するだけなら、F1を使います。
C#double value = 12.345;
Console.WriteLine(value.ToString("F1"));
C#12.3
7-2. 小数点第2位で丸める方法
小数点第2位まで残す処理は、金額、割合、測定値などでよく使います。
C#double value = 12.345;
double result = Math.Round(value, 2, MidpointRounding.AwayFromZero);
Console.WriteLine(result);
C#12.35
表示だけでよい場合は、次のように書きます。
C#double value = 12.3;
Console.WriteLine(value.ToString("F2"));
C#12.30
Math.Round(value, 2)は数値の丸め、ToString("F2")は表示形式の指定です。この2つを混同しないようにしましょう。
7-3. 小数点第3位で丸める方法
小数点第3位まで残す場合は、Math.Round(value, 3)を使います。
C#double value = 12.34567;
double result = Math.Round(value, 3, MidpointRounding.AwayFromZero);
Console.WriteLine(result);
C#12.346
表示だけ小数点第3位までにしたい場合は、F3です。
C#double value = 12.3;
Console.WriteLine($"{value:F3}");
C#12.300
測定値や分析結果など、桁数の統一が必要な場合に便利です。
7-4. Math.Powを使って任意の桁数に対応する方法
切り捨てや切り上げを任意の桁数で行いたい場合は、Math.Powを使って倍率を作ります。
C#double value = 123.4567;
int digits = 2;
double factor = Math.Pow(10, digits);
double result = Math.Truncate(value * factor) / factor;
Console.WriteLine(result);
C#123.45
切り上げならMath.Ceilingを使います。
C#double value = 123.451;
int digits = 2;
double factor = Math.Pow(10, digits);
double result = Math.Ceiling(value * factor) / factor;
Console.WriteLine(result);
C#123.46
四捨五入の場合は、Math.Roundに桁数を指定できるため、基本的にはMath.Powを使う必要はありません。
C#double value = 123.4567;
double result = Math.Round(value, 2, MidpointRounding.AwayFromZero);
Console.WriteLine(result);
C#123.46
7-5. 共通メソッド化して再利用する方法
小数点処理を複数箇所で使う場合は、共通メソッド化しておくと便利です。
C#public static class DecimalHelper
{
public static decimal Truncate(decimal value, int digits)
{
decimal factor = (decimal)Math.Pow(10, digits);
return Math.Truncate(value * factor) / factor;
}
public static decimal Ceiling(decimal value, int digits)
{
decimal factor = (decimal)Math.Pow(10, digits);
return Math.Ceiling(value * factor) / factor;
}
public static decimal Round(decimal value, int digits)
{
return Math.Round(value, digits, MidpointRounding.AwayFromZero);
}
}
使い方は次のとおりです。
C#decimal value = 123.4567m;
Console.WriteLine(DecimalHelper.Truncate(value, 2)); // 123.45
Console.WriteLine(DecimalHelper.Ceiling(value, 2)); // 123.46
Console.WriteLine(DecimalHelper.Round(value, 2)); // 123.46
業務アプリでは、丸めルールが画面ごと・帳票ごと・計算項目ごとに異なることがあります。そのため、共通メソッド化するときは、メソッド名やコメントで処理内容が明確にわかるようにしておきましょう。
8. C#の小数点処理でよくあるエラーと注意点
8-1. doubleの計算誤差で想定外の結果になる
doubleを使った小数点計算では、2進浮動小数点数による誤差が発生することがあります。
C#double value = 0.1 + 0.2;
Console.WriteLine(value);
Console.WriteLine(value == 0.3);
C#0.30000000000000004
False
このような誤差が問題になる場合は、次のいずれかで対応します。
金額計算では
decimalを使うdouble同士の比較では許容誤差を使う表示だけなら
ToStringで桁数を整える丸め処理のタイミングを明確にする
double自体が悪いわけではありません。測定値や科学技術計算ではdoubleが適している場面も多くあります。ただし、10進数として厳密な結果が必要な場面ではdecimalを検討しましょう。
8-2. Math.Roundで期待した四捨五入にならない
C#のMath.Roundでよくあるのが、「2.5を丸めたら3ではなく2になった」というケースです。
C#Console.WriteLine(Math.Round(2.5));
C#2
これは、既定の丸め方式が中間値を最も近い偶数に丸めるためです。
一般的な四捨五入を期待する場合は、MidpointRounding.AwayFromZeroを指定します。
C#Console.WriteLine(Math.Round(2.5, MidpointRounding.AwayFromZero));
C#3
小数点第2位で丸める場合も同様です。
C#decimal value = 12.345m;
decimal result = Math.Round(value, 2, MidpointRounding.AwayFromZero);
Console.WriteLine(result);
C#12.35
業務仕様で「四捨五入」と書かれている場合は、C#の既定のMath.Roundでよいのか、AwayFromZeroを使うべきなのかを確認しましょう。
8-3. ToStringで丸めたつもりでも値は変わっていない
ToString("F2")は、値を丸めたように表示しますが、元の値は変わりません。
C#double value = 123.456;
string text = value.ToString("F2");
Console.WriteLine(text); // 123.46
Console.WriteLine(value); // 123.456
この状態でvalueを使って計算を続けると、丸める前の値が使われます。
C#double value = 123.456;
Console.WriteLine(value.ToString("F2"));
double total = value * 2;
Console.WriteLine(total);
C#123.46
246.912
計算にも丸め後の値を使いたい場合は、次のようにします。
C#double value = 123.456;
double rounded = Math.Round(value, 2);
double total = rounded * 2;
Console.WriteLine(total);
C#246.92
表示用の書式指定と、数値そのものの丸め処理は分けて考えましょう。
8-4. int型へのキャストによる切り捨てに注意
小数点以下を削除する方法として、int型にキャストする方法もあります。
C#double value = 123.456;
int result = (int)value;
Console.WriteLine(result);
C#123
ただし、この方法は単純な切り捨てのように見えますが、いくつか注意点があります。
まず、戻り値がintになるため、小数型として扱いたい場合には向きません。
C#double value = 123.456;
int result = (int)value;
また、intの範囲を超える値をキャストすると問題が発生します。
C#double value = 9999999999.99;
// intの範囲を超えるため危険
int result = (int)value;
小数点以下を削除したい場合は、基本的にはMath.Truncateを使う方が意図が明確です。
C#double value = 123.456;
double result = Math.Truncate(value);
Console.WriteLine(result);
C#123
8-5. 文字列変換時のカルチャ設定に注意
ToString("N2")などの表示形式は、カルチャ設定の影響を受けます。
たとえば、日本語環境では小数点に.、桁区切りに,が使われます。
C#double value = 1234.56;
Console.WriteLine(value.ToString("N2"));
C#1,234.56
しかし、国や地域によっては小数点と桁区切りの表記が異なります。CSV出力や外部システム連携などで常に同じ形式にしたい場合は、CultureInfo.InvariantCultureを使います。
C#using System.Globalization;
double value = 1234.56;
string text = value.ToString("F2", CultureInfo.InvariantCulture);
Console.WriteLine(text);
C#1234.56
ユーザー向け画面ではローカル文化に合わせる、システム連携では固定のカルチャを使う、といった使い分けが重要です。
9. 用途別に見る小数点処理の使い分け
9-1. 計算結果を切り捨てたい場合
計算結果の小数点以下を削除したい場合は、Math.Truncateを使います。
C#double value = 123.987;
double result = Math.Truncate(value);
Console.WriteLine(result);
C#123
小数点第2位まで残して切り捨てたい場合は、次のようにします。
C#decimal value = 123.9876m;
decimal result = Math.Truncate(value * 100m) / 100m;
Console.WriteLine(result);
C#123.98
正の数だけを扱う場合はMath.Floorでも同じ結果になることがありますが、負の数を扱うならMath.Truncateとの違いに注意してください。
9-2. 一般的な四捨五入をしたい場合
一般的な四捨五入をしたい場合は、Math.RoundにMidpointRounding.AwayFromZeroを指定します。
C#decimal value = 123.455m;
decimal result = Math.Round(value, 2, MidpointRounding.AwayFromZero);
Console.WriteLine(result);
C#123.46
Math.Round(value, 2)だけでも丸めはできますが、中間値で偶数丸めになる場合があります。業務上「5以上は切り上げ」が求められる場合は、丸め方式を明示しましょう。
9-3. 常に切り上げたい場合
常に上方向に丸めたい場合は、Math.Ceilingを使います。
C#double value = 123.001;
double result = Math.Ceiling(value);
Console.WriteLine(result);
C#124
小数点第2位で切り上げたい場合は、次のようにします。
C#decimal value = 123.451m;
decimal result = Math.Ceiling(value * 100m) / 100m;
Console.WriteLine(result);
C#123.46
ただし、負の数ではMath.Ceiling(-123.451)が-123になる点に注意が必要です。
9-4. 画面表示だけ整えたい場合
画面表示だけ整えたい場合は、ToStringや文字列補間を使います。
C#double value = 123.4;
Console.WriteLine(value.ToString("F2"));
Console.WriteLine($"{value:F2}");
C#123.40
123.40
桁区切り付きで表示したい場合は、N2を使います。
C#decimal amount = 1234567.8m;
Console.WriteLine($"{amount:N2}");
C#1,234,567.80
この方法は表示用であり、値そのものは変わりません。計算結果として丸めたい場合は、Math.Roundなどを使いましょう。
9-5. 金額計算で安全に処理したい場合
金額計算では、基本的にdecimalを使います。
C#decimal price = 1980m;
decimal taxRate = 0.10m;
decimal tax = Math.Round(price * taxRate, 0, MidpointRounding.AwayFromZero);
decimal total = price + tax;
Console.WriteLine(total);
C#2178
金額計算では、次の点を明確にしておくことが重要です。
税額はどのタイミングで丸めるのか
小数点以下は切り捨て、四捨五入、切り上げのどれか
商品単位で丸めるのか、合計後に丸めるのか
表示だけ丸めるのか、値そのものを丸めるのか
doubleではなくdecimalを使っているか
金額処理では、丸め方が1円単位の差につながります。仕様を明確にし、decimalと適切な丸め処理を組み合わせましょう。
10. C#の小数点処理に関するよくある質問
10-1. C#で小数点以下を削除するには?
C#で小数点以下を削除するには、Math.Truncateを使います。
C#double value = 123.456;
double result = Math.Truncate(value);
Console.WriteLine(result);
C#123
Math.Truncateは小数点以下を取り除き、0方向に丸めます。正の数では単純な切り捨てと同じ結果になります。
負の数を扱う場合は、Math.Floorとの違いに注意してください。
C#Console.WriteLine(Math.Truncate(-123.456)); // -123
Console.WriteLine(Math.Floor(-123.456)); // -124
10-2. C#で小数点第2位まで表示するには?
小数点第2位まで表示したい場合は、ToString("F2")を使います。
C#double value = 123.4;
Console.WriteLine(value.ToString("F2"));
C#123.40
文字列補間を使う場合は、次のように書けます。
C#double value = 123.4;
Console.WriteLine($"{value:F2}");
C#123.40
桁区切りも付けたい場合は、N2を使います。
C#decimal amount = 1234567.8m;
Console.WriteLine($"{amount:N2}");
C#1,234,567.80
10-3. Math.Roundが四捨五入にならないのはなぜ?
Math.Roundが期待した四捨五入にならない理由は、既定の丸め方式が一般的な四捨五入とは異なる場合があるためです。
C#Console.WriteLine(Math.Round(2.5));
C#2
これは、中間値を最も近い偶数に丸める「銀行丸め」が使われるためです。
一般的な四捨五入をしたい場合は、MidpointRounding.AwayFromZeroを指定します。
C#Console.WriteLine(Math.Round(2.5, MidpointRounding.AwayFromZero));
C#3
小数点第2位で丸める場合は次のようにします。
C#decimal value = 12.345m;
decimal result = Math.Round(value, 2, MidpointRounding.AwayFromZero);
Console.WriteLine(result);
C#12.35
10-4. doubleとdecimalはどちらを使うべき?
用途によって使い分けます。
| 用途 | 適した型 |
|---|---|
| 一般的な小数計算 | double |
| 科学技術計算 | double |
| ゲームや大量データ | float |
| 金額計算 | decimal |
| 税率・請求金額 | decimal |
金額や税率など、10進数として正確に扱いたい場合はdecimalを使います。測定値や統計計算などではdoubleがよく使われます。
C#double measurement = 12.345;
decimal price = 1234.56m;
迷った場合は、金額ならdecimal、それ以外の一般的な数値計算ならdoubleを基本に考えるとよいでしょう。
10-5. 小数点以下を0埋めして表示するには?
小数点以下を0埋めして表示するには、F指定子またはカスタム書式を使います。
C#double value = 12.3;
Console.WriteLine(value.ToString("F2"));
C#12.30
カスタム書式を使う場合は、次のように書きます。
C#double value = 12.3;
Console.WriteLine(value.ToString("0.00"));
C#12.30
小数点以下3桁で0埋めしたい場合は、F3または0.000を使います。
C#double value = 12.3;
Console.WriteLine(value.ToString("F3"));
Console.WriteLine(value.ToString("0.000"));
C#12.300
12.300
不要な0を表示したくない場合は、#を使います。
C#double value = 12.3;
Console.WriteLine(value.ToString("0.##"));
C#12.3
まとめ
C#の小数点処理では、目的に応じて使うメソッドや書式を正しく選ぶことが重要です。
小数点以下を削除したい場合はMath.Truncate、指定値以下に丸めたい場合はMath.Floor、指定値以上に丸めたい場合はMath.Ceilingを使います。四捨五入にはMath.Roundを使いますが、既定では中間値が偶数丸めになる場合があるため、一般的な四捨五入をしたいときはMidpointRounding.AwayFromZeroを明示しましょう。
また、表示だけを整えたい場合は、ToString("F2")や$"{value:F2}"のような書式指定を使います。ただし、表示桁数の指定は値そのものを変更しない点に注意が必要です。
最後に、金額計算ではdoubleではなくdecimalを使うのが基本です。C#で小数点を扱うときは、次のように使い分けると整理しやすくなります。
| 目的 | 方法 |
|---|---|
| 小数点以下を削除 | Math.Truncate(value) |
| 小数点以下を切り下げ | Math.Floor(value) |
| 小数点以下を切り上げ | Math.Ceiling(value) |
| 小数点第n位で四捨五入 | Math.Round(value, n, MidpointRounding.AwayFromZero) |
| 小数点第n位まで表示 | value.ToString("Fn") |
| 桁区切り付きで表示 | value.ToString("N2") |
| 金額計算 | decimalを使う |
C#の小数点処理は、メソッドごとの違いを理解すれば難しくありません。値を変更したいのか、表示だけを整えたいのかを意識しながら、用途に合った方法を選びましょう。

