C#で小数を切り捨てる方法|Math.Floor・Truncate・intキャストの違いと桁数指定まで解説

はじめに

C#で小数を切り捨てる方法には、主にMath.FloorMath.Truncateintへのキャストがあります。

正の数だけを扱う場合、これらは同じ結果になることが多いため、違いを意識せずに使ってしまいがちです。しかし、負の数を処理すると、Math.FloorMath.Truncateでは結果が異なります。また、intキャストでは戻り値の型やオーバーフローにも注意が必要です。

この記事では、C#で小数を切り捨てる基本的な方法から、小数点以下の桁数を指定する方法、doubledecimalを扱う際の注意点まで、コード例を交えて解説します。

1. C#で小数を切り捨てる基本

1-1. 「切り捨て」とは小数点以下を取り除く処理

切り捨てとは、指定した位置より下の桁を取り除く処理です。

たとえば、12.345の小数点以下をすべて取り除くと、結果は12になります。

12.345 → 12

小数第2位まで残して、それより下を切り捨てる場合は次の結果になります。

12.345 → 12.34

ただし、負の数では「小数部分を単純に取り除く」のか、「数値が小さい方向に丸める」のかによって結果が変わります。

-12.345 → -12-12.345 → -13

C#で切り捨て処理を実装するときは、どちらの結果を求めているのかを明確にすることが重要です。

1-2. C#でよく使う切り捨て方法は3種類

C#で小数を切り捨てる代表的な方法は、次の3種類です。

double value = 12.345;

// 負の無限大方向へ丸めるdouble floorValue = Math.Floor(value);

// 小数部分を取り除くdouble truncateValue = Math.Truncate(value);

// 小数部分を取り除き、int型に変換するint intValue = (int)value;

それぞれの特徴は次のとおりです。

  • Math.Floor:元の値以下で最大の整数値を返す

  • Math.Truncate:小数部分を取り除き、0方向へ丸める

  • intキャスト:小数部分を取り除き、結果をint型に変換する

1-3. Math.Floor・Math.Truncate・intキャストの使い分け早見表

方法正の数12.8負の数-12.8戻り値主な用途
Math.Floor12-13doubleまたはdecimal常に小さい方向へ丸める
Math.Truncate12-12doubleまたはdecimal小数部分だけを取り除く
(int)キャスト12-12int小数部分を取り除いて整数型に変換する

負の数を扱わない場合は、どの方法でも同じ結果になることがあります。しかし、処理の意味や戻り値の型は異なるため、用途に合わせて選ぶ必要があります。

2. Math.Floorで小数を切り捨てる方法

2-1. Math.Floorの基本構文

Math.Floorは、指定した値以下で最大となる整数値を返すメソッドです。

基本構文は次のとおりです。

double result = Math.Floor(doubleValue);decimal resultDecimal = Math.Floor(decimalValue);

Math.Floorには、double型用とdecimal型用のオーバーロードがあります。

2-2. 正の数をMath.Floorで切り捨てる例

正の小数にMath.Floorを使用すると、小数点以下が取り除かれます。

double value = 12.8;double result = Math.Floor(value);

Console.WriteLine(result); // 12

12.8以下で最大の整数値は12であるため、結果は12です。

別の例も確認してみましょう。

Console.WriteLine(Math.Floor(3.14));  // 3Console.WriteLine(Math.Floor(9.99));  // 9Console.WriteLine(Math.Floor(5.0));   // 5

すでに整数である値を渡した場合、値は変化しません。

2-3. 負の数をMath.Floorで処理する場合の注意点

Math.Floorを負の数に使用すると、0から遠ざかる方向に丸められます。

double value = -12.8;double result = Math.Floor(value);

Console.WriteLine(result); // -13

-12.8以下で最大の整数値は-13です。そのため、小数部分を単純に取り除いた-12にはなりません。

Console.WriteLine(Math.Floor(-3.14)); // -4Console.WriteLine(Math.Floor(-9.99)); // -10Console.WriteLine(Math.Floor(-5.0));  // -5

「負の数でも小数部分だけを取り除きたい」という場合は、Math.FloorではなくMath.Truncateを使用します。

2-4. Math.Floorの戻り値の型

Math.Floorは、整数に相当する値を返しますが、戻り値の型が整数型になるわけではありません。

double value = 12.8;double result = Math.Floor(value);

この場合、resultの型はdoubleです。値は12ですが、内部的には12.0として扱われます。

decimal型を渡した場合は、戻り値もdecimal型です。

decimal value = 12.8m;decimal result = Math.Floor(value);

Console.WriteLine(result); // 12

戻り値をint型にしたい場合は、範囲を確認したうえで明示的に変換します。

double value = 12.8;int result = checked((int)Math.Floor(value));

Console.WriteLine(result); // 12

3. Math.Truncateで小数を切り捨てる方法

3-1. Math.Truncateの基本構文

Math.Truncateは、数値の小数部分を取り除くメソッドです。

double result = Math.Truncate(doubleValue);decimal resultDecimal = Math.Truncate(decimalValue);

Math.Floorとは異なり、正の数でも負の数でも0に近づく方向へ処理されます。

3-2. 正の数をMath.Truncateで切り捨てる例

正の数にMath.Truncateを使用すると、小数部分がそのまま取り除かれます。

double value = 12.8;double result = Math.Truncate(value);

Console.WriteLine(result); // 12

ほかの例は次のとおりです。

Console.WriteLine(Math.Truncate(3.14)); // 3Console.WriteLine(Math.Truncate(9.99)); // 9Console.WriteLine(Math.Truncate(5.0));  // 5

正の数では、Math.Floorと同じ結果になります。

3-3. 負の数をMath.Truncateで処理する場合の挙動

負の数にMath.Truncateを使用した場合も、小数部分だけが取り除かれます。

double value = -12.8;double result = Math.Truncate(value);

Console.WriteLine(result); // -12

Math.Truncateは0方向へ丸めるため、-12.8-12になります。

Console.WriteLine(Math.Truncate(-3.14)); // -3Console.WriteLine(Math.Truncate(-9.99)); // -9Console.WriteLine(Math.Truncate(-5.0));  // -5

「整数部分を残し、小数点以下だけを削除する」という意味で切り捨てたい場合は、Math.Truncateが適しています。

3-4. Math.Floorとの違い

Math.FloorMath.Truncateの違いは、負の数を処理すると明確になります。

double value = -12.8;

Console.WriteLine(Math.Floor(value)); // -13Console.WriteLine(Math.Truncate(value)); // -12

Math.Floorは負の無限大方向、Math.Truncateは0方向へ処理します。

数直線で考えると、次のような違いです。

Math.Floor(-12.8)    → -13Math.Truncate(-12.8) → -12

正の数では結果が同じでも、負の数では異なるため、入力値に負数が含まれる可能性がある場合は注意しましょう。

4. intキャストで小数を切り捨てる方法

4-1. intキャストの基本構文

小数型の値をint型へ明示的にキャストすると、小数部分が取り除かれます。

int result = (int)value;

たとえば、次のように記述します。

double value = 12.8;int result = (int)value;

Console.WriteLine(result); // 12

キャスト後の値はint型になるため、整数として後続処理に使用できます。

4-2. doubleやdecimalをintに変換する例

double型をint型に変換する例は次のとおりです。

double value = 123.456;int result = (int)value;

Console.WriteLine(result); // 123

負の数でも、0方向に小数部分が取り除かれます。

double value = -123.456;int result = (int)value;

Console.WriteLine(result); // -123

decimal型も同様に変換できます。

decimal price = 1980.75m;int result = (int)price;

Console.WriteLine(result); // 1980

ただし、変換対象の値がint型の範囲内に収まっている必要があります。

4-3. intキャストとMath.Truncateの違い

intキャストとMath.Truncateは、どちらも小数部分を取り除き、0方向へ処理します。

double value = -12.8;

Console.WriteLine((int)value); // -12Console.WriteLine(Math.Truncate(value)); // -12

主な違いは戻り値の型です。

double truncated = Math.Truncate(12.8); // doubleint converted = (int)12.8;              // int

元の数値型を維持したい場合はMath.Truncate、整数型へ変換したい場合はキャストが適しています。

また、intには表現できる範囲があるため、大きな数値を扱う場合は注意が必要です。

4-4. オーバーフローに注意が必要なケース

doubledecimalの値がint型の範囲を超えている場合、正常に変換できません。

安全に変換したい場合は、checkedを使用します。

double value = 3_000_000_000;

try{int result = checked((int)value);Console.WriteLine(result);}catch (OverflowException){Console.WriteLine("int型の範囲を超えています。");}

事前に範囲を確認する方法もあります。

double value = 3_000_000_000;

if (double.IsFinite(value) &&value >= int.MinValue &&value <= int.MaxValue){int result = (int)value;Console.WriteLine(result);}else{Console.WriteLine("int型へ変換できない値です。");}

double型では、NaNや正負の無限大が含まれる可能性もあります。外部入力や計算結果をキャストする場合は、有限値であることも確認しましょう。

5. Math.Floor・Math.Truncate・intキャストの違い

5-1. 正の数では結果が同じになることが多い

正の数の小数点以下をすべて取り除く場合、3つの方法は同じ数値になります。

double value = 12.8;

Console.WriteLine(Math.Floor(value)); // 12Console.WriteLine(Math.Truncate(value)); // 12Console.WriteLine((int)value); // 12

ただし、Math.FloorMath.Truncateの戻り値はdouble、キャストの戻り値はintです。

結果として表示される数値だけでなく、処理の意味と戻り値の型を考えて選びましょう。

5-2. 負の数ではMath.FloorとTruncate・intキャストで結果が変わる

負の数では、Math.Floorだけ結果が異なります。

double value = -12.8;

double floorResult = Math.Floor(value);double truncateResult = Math.Truncate(value);int castResult = (int)value;

Console.WriteLine(floorResult); // -13Console.WriteLine(truncateResult); // -12Console.WriteLine(castResult); // -12

Math.Floorは値が小さくなる方向へ処理します。一方、Math.Truncateintキャストは、0に近づく方向へ小数部分を取り除きます。

5-3. 戻り値の型の違い

各方法の戻り値は次のように異なります。

double doubleValue = 12.8;decimal decimalValue = 12.8m;

double floorDouble = Math.Floor(doubleValue);decimal floorDecimal = Math.Floor(decimalValue);

double truncateDouble = Math.Truncate(doubleValue);decimal truncateDecimal = Math.Truncate(decimalValue);

int castValue = (int)doubleValue;

Math.FloorMath.Truncateは、渡した値に対応するdoubleまたはdecimalを返します。

一方、intキャストは必ずint型へ変換します。小数部分を取り除くだけでなく、データ型そのものを変える点が大きな違いです。

5-4. 用途別のおすすめの使い分け

常に元の値以下へ丸めたい場合は、Math.Floorが適しています。

double pageIndex = Math.Floor(position / pageSize);

正負にかかわらず小数部分だけを取り除きたい場合は、Math.Truncateを使用します。

double integerPart = Math.Truncate(value);

結果をint型として利用したい場合は、範囲を確認したうえでキャストします。

int count = checked((int)value);

判断に迷う場合は、次の基準で選ぶとよいでしょう。

目的適した方法
負の数も含めて常に小さい方向へ丸めるMath.Floor
小数部分だけを取り除くMath.Truncate
小数部分を取り除いてint型にするintキャスト
金額などを指定桁数で切り捨てるdecimalMath.Truncateなどを組み合わせる

6. 小数点以下の桁数を指定して切り捨てる方法

6-1. 小数第1位で切り捨てる方法

小数第1位まで残し、小数第2位以降を切り捨てるには、値を10倍してからMath.Truncateし、再び10で割ります。

double value = 12.345;double result = Math.Truncate(value * 10) / 10;

Console.WriteLine(result); // 12.3

処理の流れは次のとおりです。

12.345 × 10 = 123.45Math.Truncate(123.45) = 123123 ÷ 10 = 12.3

この方法では、負の数でも小数部分を0方向へ取り除きます。

double value = -12.345;double result = Math.Truncate(value * 10) / 10;

Console.WriteLine(result); // -12.3

6-2. 小数第2位で切り捨てる方法

小数第2位まで残し、小数第3位以降を切り捨てる場合は100倍します。

double value = 12.3456;double result = Math.Truncate(value * 100) / 100;

Console.WriteLine(result); // 12.34

decimal型の場合は、定数にもmを付けます。

decimal value = 12.3456m;decimal result = Math.Truncate(value * 100m) / 100m;

Console.WriteLine(result); // 12.34

負の数を数値が小さくなる方向へ処理したい場合は、Math.Truncateの代わりにMath.Floorを使用します。

decimal value = -12.3456m;decimal result = Math.Floor(value * 100m) / 100m;

Console.WriteLine(result); // -12.35

6-3. 小数第n位で切り捨てる汎用メソッド

double型の値を指定した桁数で切り捨てるメソッドは、次のように実装できます。

static double Truncate(double value, int digits){if (digits < 0 || digits > 15){throw new ArgumentOutOfRangeException(nameof(digits),"digitsは0から15の範囲で指定してください。");}

double factor = Math.Pow(10, digits);return Math.Truncate(value * factor) / factor;

}

使用例は次のとおりです。

double value = 12.345678;

Console.WriteLine(Truncate(value, 0)); // 12Console.WriteLine(Truncate(value, 1)); // 12.3Console.WriteLine(Truncate(value, 2)); // 12.34Console.WriteLine(Truncate(value, 3)); // 12.345

decimal型では、MidpointRounding.ToZeroを利用すると、乗算によるオーバーフローのリスクを抑えながら指定桁数で切り捨てられます。

static decimal Truncate(decimal value, int digits){if (digits < 0 || digits > 28){throw new ArgumentOutOfRangeException(nameof(digits),"digitsは0から28の範囲で指定してください。");}

return decimal.Round(value, digits, MidpointRounding.ToZero);

}

使用例は次のとおりです。

decimal value = 12.345678m;

Console.WriteLine(Truncate(value, 0)); // 12Console.WriteLine(Truncate(value, 1)); // 12.3Console.WriteLine(Truncate(value, 2)); // 12.34

MidpointRounding.ToZeroは、正の数と負の数の両方を0方向へ丸めます。

6-4. decimalで金額計算を切り捨てる例

金額計算では、2進浮動小数点数であるdoubleよりも、10進数を扱うdecimalが適しています。

たとえば、税率を掛けた結果を1円未満で切り捨てる処理は次のように実装できます。

decimal price = 1_980m;decimal taxRate = 0.10m;

decimal tax = Math.Truncate(price * taxRate);decimal total = price + tax;

Console.WriteLine(tax); // 198Console.WriteLine(total); // 2178

割引後の価格を小数第2位まで残す場合は、次のように記述できます。

decimal price = 1_234.567m;decimal discountedPrice =decimal.Round(price * 0.9m, 2, MidpointRounding.ToZero);

Console.WriteLine(discountedPrice); // 1111.11

実際の業務では、消費税や手数料を商品単位で切り捨てるのか、合計後に切り捨てるのかによって結果が変わります。計算方法だけでなく、業務上のルールも確認しましょう。

6-5. doubleで桁数指定する場合の誤差に注意

doubleは、多くの10進小数を内部で正確に表現できません。

たとえば、次の計算結果は、期待する値からわずかにずれる可能性があります。

double value = 1.2;double result = value * 10;

Console.WriteLine(result);

指定桁数で切り捨てるために10倍や100倍をすると、内部誤差の影響で意図しない結果になることがあります。

double value = 1.005;double result = Math.Truncate(value * 100) / 100;

Console.WriteLine(result);

金額や税額のように10進数の正確さが重要な処理では、decimalを使用します。

decimal value = 1.005m;decimal result = decimal.Round(value,2,MidpointRounding.ToZero);

Console.WriteLine(result); // 1.00

測定値や科学計算などでdoubleを使用する場合は、切り捨て前後に誤差が含まれる可能性を考慮しましょう。

7. 整数部分を残して小数点以下を切り捨てる実装例

7-1. double型の小数を切り捨てるコード例

double型の整数部分を残し、小数点以下を取り除く場合はMath.Truncateを使用します。

double value = 123.456;double result = Math.Truncate(value);

Console.WriteLine(result); // 123

負の数でも整数部分が残ります。

double value = -123.456;double result = Math.Truncate(value);

Console.WriteLine(result); // -123

7-2. decimal型の小数を切り捨てるコード例

decimal型でも、基本的な使い方は同じです。

decimal value = 123.456m;decimal result = Math.Truncate(value);

Console.WriteLine(result); // 123

金額を整数単位に切り捨てたい場合にも利用できます。

decimal amount = 9_876.54m;decimal result = Math.Truncate(amount);

Console.WriteLine(result); // 9876

7-3. float型の小数を切り捨てるコード例

Math.Truncateにはfloat型専用のオーバーロードがありません。そのため、floatを渡すとdoubleへ暗黙的に変換され、戻り値もdoubleになります。

float value = 123.456f;double result = Math.Truncate(value);

Console.WriteLine(result); // 123

結果をfloat型として受け取りたい場合は、明示的にキャストします。

float value = 123.456f;float result = (float)Math.Truncate(value);

Console.WriteLine(result); // 123

ただし、小数部分を取り除いた結果を整数として使うのであれば、値の範囲を確認して整数型へ変換する方法もあります。

7-4. 戻り値をintにしたい場合のコード例

戻り値をint型にしたい場合は、キャストを使用します。

double value = 123.456;int result = checked((int)value);

Console.WriteLine(result); // 123

Math.Truncateの結果を変換することもできます。

double value = 123.456;int result = checked((int)Math.Truncate(value));

Console.WriteLine(result); // 123

単純な変換であれば、最初からintへキャストするだけで十分です。

一方、処理の途中ではdoubledecimalのまま整数相当の値を保持し、最後に必要な型へ変換したい場合は、Math.Truncateを使うと意図が明確になります。

8. C#で切り捨て処理を使うときの注意点

8-1. 四捨五入にはMath.Roundを使う

切り捨てと四捨五入は異なる処理です。

double value = 12.8;

Console.WriteLine(Math.Truncate(value)); // 12Console.WriteLine(Math.Round(value)); // 13

Math.Truncateは小数部分を取り除きますが、Math.Roundは指定された丸め規則に従って最も近い値へ丸めます。

小数第2位まで四捨五入する場合は、次のように記述します。

double value = 12.345;double result = Math.Round(value,2,MidpointRounding.AwayFromZero);

Console.WriteLine(result); // 12.35

なお、Math.Roundの既定の中間値処理は、一般に「銀行丸め」と呼ばれる偶数方向への丸めです。期待する仕様に応じて、MidpointRoundingを明示しましょう。

8-2. 表示だけ小数を消したい場合は書式指定を使う

値そのものを変更せず、画面表示だけ小数点以下を消したい場合は書式指定を使用できます。

double value = 12.8;

Console.WriteLine(value.ToString("0")); // 13

ただし、"0"による書式指定は表示時に丸めを行うため、切り捨てとは限りません。

表示でも確実に切り捨てたい場合は、先にMath.Truncateなどで値を処理します。

double value = 12.8;string text = Math.Truncate(value).ToString("0");

Console.WriteLine(text); // 12

小数第2位まで切り捨てて表示する場合は、次のように記述できます。

decimal value = 12.349m;decimal truncated =decimal.Round(value, 2, MidpointRounding.ToZero);

Console.WriteLine(truncated.ToString("0.00")); // 12.34

書式指定は表示内容を変えるだけで、元の変数に格納された値は変わりません。

8-3. 金額計算ではdecimalを使う

doublefloatは2進浮動小数点数であり、10進小数を正確に表現できない場合があります。

double value = 0.1 + 0.2;Console.WriteLine(value);

金額、税率、利率など、10進数の桁が重要な処理ではdecimalを使用するのが基本です。

decimal price = 1000m;decimal rate = 0.08m;decimal fee = Math.Truncate(price * rate);

Console.WriteLine(fee); // 80

ただし、decimalを使用すれば業務ルールまで自動的に正しくなるわけではありません。どの段階で何桁を切り捨てるかも明確に設計する必要があります。

8-4. 負の数を扱う場合は仕様を確認する

負の数に対する切り捨てでは、期待する結果を明確にする必要があります。

double value = -3.8;

Console.WriteLine(Math.Floor(value)); // -4Console.WriteLine(Math.Truncate(value)); // -3Console.WriteLine((int)value); // -3

たとえば、損益、温度、座標、残高などでは負の値が発生することがあります。

「常に元の値以下にする」という仕様ならMath.Floor、「小数部分だけを削除する」という仕様ならMath.Truncateが適しています。

メソッド名だけで判断せず、正の数と負の数の両方をテストしましょう。

double[] values = { 3.8, -3.8 };

foreach (double value in values){Console.WriteLine($"値: {value}, Floor: {Math.Floor(value)}, " +$"Truncate: {Math.Truncate(value)}");}

9. C#の切り捨てに関するよくある質問

9-1. Math.FloorとMath.Truncateはどちらを使うべき?

求める結果によって使い分けます。

元の数値以下で最大の整数値を求める場合は、Math.Floorを使用します。

Math.Floor(-5.7); // -6

正負にかかわらず小数部分だけを取り除く場合は、Math.Truncateを使用します。

Math.Truncate(-5.7); // -5

正の数だけを扱う場合は同じ結果になりますが、負の数が入力される可能性を考慮して選びましょう。

9-2. intキャストで切り捨てても問題ない?

結果をint型として使用し、変換元の値がintの範囲内であることが保証されていれば、intキャストを使用できます。

double value = 12.9;int result = (int)value;

Console.WriteLine(result); // 12

ただし、次の点に注意が必要です。

  • 結果の型がintになる

  • 小数部分は0方向に取り除かれる

  • 大きすぎる値や小さすぎる値は安全に変換できない

  • doubleではNaNや無限大が入力される可能性がある

安全性を高めたい場合は、範囲チェックやcheckedを使用します。

9-3. 小数第2位まで残して切り捨てるには?

小数第2位まで残し、小数第3位以降を切り捨てるには、Math.Truncateを使用して次のように処理できます。

double value = 12.3456;double result = Math.Truncate(value * 100) / 100;

Console.WriteLine(result); // 12.34

decimal型では、MidpointRounding.ToZeroを指定する方法もあります。

decimal value = 12.3456m;decimal result = decimal.Round(value,2,MidpointRounding.ToZero);

Console.WriteLine(result); // 12.34

金額計算では、後者のようにdecimalを使用する方法が適しています。

9-4. 切り捨てと四捨五入の違いは?

切り捨ては、指定した桁より下を取り除く処理です。

12.89を整数に切り捨てる → 12

四捨五入は、次の桁の値に応じて切り上げるか切り下げるかを決めます。

12.89を整数に四捨五入する → 13

C#では、切り捨てにMath.TruncateMath.Floor、四捨五入にMath.Roundを使用します。

double value = 12.89;

Console.WriteLine(Math.Truncate(value)); // 12Console.WriteLine(Math.Round(value)); // 13

9-5. decimalとdoubleではどちらを使うべき?

用途に応じて選びます。

金額、税金、料金、会計値など、10進数の正確さを重視する場合はdecimalが適しています。

decimal price = 1234.56m;

科学計算、画像処理、統計処理、測定値など、広い範囲と高速な浮動小数点演算を重視する場合はdoubleがよく使用されます。

double distance = 1234.56;

切り捨てる桁が業務上重要な場合は、単に型を選ぶだけでなく、丸める位置や方向も明示的に実装しましょう。

まとめ

C#で小数を切り捨てる代表的な方法は、Math.FloorMath.Truncateintキャストの3種類です。

Math.Floorは元の値以下で最大の整数値を返すため、負の数では0から遠ざかる方向へ処理されます。

Math.Floor(-12.8); // -13

Math.Truncateは小数部分を取り除き、0方向へ処理します。

Math.Truncate(-12.8); // -12

intキャストも小数部分を0方向へ取り除きますが、結果の型がintになり、変換可能な範囲にも制限があります。

(int)-12.8; // -12

小数点以下の桁数を指定する場合は、10のべき乗を掛けてからMath.Truncateする方法があります。

double result = Math.Truncate(value * 100) / 100;

金額計算ではdecimalを使用し、MidpointRounding.ToZeroで指定桁数を切り捨てる方法も有効です。

decimal result = decimal.Round(value,2,MidpointRounding.ToZero);

正の数だけでなく負の数の結果も確認し、処理の目的、戻り値の型、必要な桁数に合わせて適切な方法を選びましょう。