DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

小数点を切り捨て、切り上げ、四捨五入する

ここでは、数値の端数処理(丸め、整数化)を行う方法を説明します。

切り捨てる

小数点以下を切り捨てるには、Mathクラス(System名前空間)のFloorまたはTruncateメソッドを使用します。

正の数を丸めるのであれば、どちらのメソッドも同じ結果(整数部分をそのまま残して小数点以下を0とする)になります。違いが現れるのは、負の数を丸めた時です。負の数を丸めた時、Floorメソッドはより小さな整数に丸められ(負の無限大への丸め)、Truncateメソッドはより大きな整数に丸められます(0への丸め)。例えば -1.5 を丸めると、Floorでは -2 、Truncateでは -1 になります。

VB.NETのInt関数はFloorメソッドと同じ丸め方をし、Fix関数はTruncateメソッドと同じ丸め方をします。

C#では、キャストで小数を整数に変換すると、Truncateメソッドと同じ丸め方をします。

以下に、FloorメソッドとTruncateメソッドを使って 1.5 と -1.5 を丸めた結果を取得する例を示します。

VB.NET
コードを隠すコードを選択
Dim val As Double = 1.5

Dim ret1 As Double = Math.Floor(val)
'1
Dim ret2 As Double = Math.Truncate(val)
'1

Dim ret3 As Double = Math.Floor(-val)
'-2
Dim ret4 As Double = Math.Truncate(-val)
'-1
C#
コードを隠すコードを選択
double val = 1.5;

double ret1 = Math.Floor(val);
//1
double ret2 = Math.Truncate(val);
//1

double ret3 = Math.Floor(-val);
//-2
double ret4 = Math.Truncate(-val);
//-1

切り上げる

小数点以下を切り上げる(小数点以下が0でなかったら整数部分を1増やして小数点以下を0とする)には、MathクラスのCeilingメソッドを使用します。

正の数も負の数もCeilingメソッドで丸めると、より大きな整数に丸められます(正の無限大への丸め)。例えば -1.5 の場合、Ceilingメソッドは -1 を返します。

VB.NET
コードを隠すコードを選択
Dim val As Double = 1.5

Dim ret1 As Double = Math.Ceiling(val)
'2

Dim ret3 As Double = Math.Ceiling(-val)
'-1
C#
コードを隠すコードを選択
double val = 1.5;

double ret1 = Math.Ceiling(val);
//2

double ret3 = Math.Ceiling(-val);
//-1

四捨五入する

四捨五入する(端数が0.5未満なら切り捨て、0.5以上なら切り上げる)には、MathクラスのRoundメソッドを使用します。

ただし端数が0.5の時は、Roundメソッドの返す値は、通常の四捨五入とは異なる可能性があります。四捨五入では0.5を常に切り上げますが、Roundメソッドは丸めた結果が偶数になるような丸め方をします。例えば 1.5 をRoundメソッドで丸めると 2 になりますが、 2.5 を丸めると 3 ではなく、 2 になります。このような丸め方は、「最近接偶数への丸め」「最近偶数丸め」「銀行家の丸め」などと呼ばれます。IEEE 754で定められているのはこの方法ですので、浮動小数点数の丸め方としては通常の四捨五入より一般的な方法と言えます。

補足:なぜこのようなややこしい丸め方を使うのかというと、丸めた値をたくさん足していった時に、0.5を常に大きな値に丸めた時よりも誤差を小さくすることができるためです。

ConvertクラスのToInt32やToInt64メソッドなどで小数を整数に変換した時もRoundメソッドと同じ丸め方をします。また、VB.NETのCIntやCLng関数、さらにはCType関数によって整数に変換した時もRoundメソッドと同じ丸め方をします。

VB.NET
コードを隠すコードを選択
Dim ret1 As Double = Math.Round(1.5)
'2
Dim ret2 As Double = Math.Round(2.5)
'2

Dim ret3 As Double = Math.Round(-1.5)
'-2
Dim ret4 As Double = Math.Round(-2.5)
'-2
C#
コードを隠すコードを選択
double ret1 = Math.Round(1.5);
//2
double ret2 = Math.Round(2.5);
//2

double ret3 = Math.Round(-1.5);
//-2
double ret4 = Math.Round(-2.5);
//-2

.NET Framework 2.0からは、Roundメソッドで四捨五入もできるようになりました。四捨五入するには、Roundメソッドの2番目のパラメータにMidpointRounding.AwayFromZeroを指定します。

VB.NET
コードを隠すコードを選択
Dim ret1 As Double = Math.Round(1.5, MidpointRounding.AwayFromZero)
'2
Dim ret2 As Double = Math.Round(2.5, MidpointRounding.AwayFromZero)
'3

Dim ret3 As Double = Math.Round(-1.5, MidpointRounding.AwayFromZero)
'-2
Dim ret4 As Double = Math.Round(-2.5, MidpointRounding.AwayFromZero)
'-3
C#
コードを隠すコードを選択
double ret1 = Math.Round(1.5, MidpointRounding.AwayFromZero);
//2
double ret2 = Math.Round(2.5, MidpointRounding.AwayFromZero);
//3

double ret3 = Math.Round(-1.5, MidpointRounding.AwayFromZero);
//-2
double ret4 = Math.Round(-2.5, MidpointRounding.AwayFromZero);
//-3

なおRoundメソッドは、小数点以下のどの桁で丸めるか(小数点第何位で丸めるか)を2番目のパラメータに指定することもできます。

補足:特定の桁で切り捨て、または、切り上げをするメソッドは用意されていません。これを行うには、値を数十倍してから小数点以下を丸めて、その値を数十分の1にするという方法になります。例えば 1.23456789 を小数点第3位で切り捨てて 1.23 にするには、「Math.Truncate(1.23456789 * 100.0) / 100.0」のようにします。

ちょっと邪道でおすすめは出来ませんが、数値を数値書式指定文字列を使って文字列に変換し、それをまた数値に戻すという方法でも四捨五入を行うことができます。

VB.NET
コードを隠すコードを選択
Dim val As Double = 2.5

'小数部を0桁とする
Dim s As String = val.ToString("F0")
'Dim s As String = val.ToString("#")
Dim ret1 As Double = Double.Parse(s)
'3
C#
コードを隠すコードを選択
double val = 2.5;

//小数部を0桁とする
string s = val.ToString("F0");
//string s = val.ToString("#");
double ret1 = double.Parse(s);
//3

まとめ

ここで紹介したメソッドや関数がどのような値を返すかを表にまとめます。

val -1.8 -1.5 -1.2 2.2 2.5 2.8 (丸め方)
Math.Floor(val) -2 -2 -2 2 2 2 負の無限大への丸め
Int(val)
(VB.NETのみ)
-2 -2 -2 2 2 2
Math.Truncate(val) -1 -1 -1 2 2 2 0への丸め
(int)val
(C#のみ)
-1 -1 -1 2 2 2
Fix(val)
(VB.NETのみ)
-1 -1 -1 2 2 2
Math.Ceiling(val) -1 -1 -1 3 3 3 正の無限大への丸め
Math.Round(val) -2 -2 -1 2 2 3 最近接偶数への丸め
(銀行家の丸め)
Convert.ToInt32(val) -2 -2 -1 2 2 3
CInt(val)
(VB.NETのみ)
-2 -2 -1 2 2 3
CType(val, Integer)
(VB.NETのみ)
-2 -2 -1 2 2 3
Math.Round(val,
MidpointRounding.AwayFromZero)
-2 -2 -1 2 3 3 四捨五入
  • 履歴:
  • 2011/3/11 表内の間違いを修正。