いろいろハマるのでまとめておきますね。
# ご指摘をいただいた箇所を修正
// 整数型の宣言
// m を省略すると、double 型の値になる。
// つまり decimal d1 = (double)12.5; と同じであり危険(誤差がでる)
// [追記] 通常 2^(-n) は誤差が出ない
decimal[] d = new decimal[4];
d[0] = 12.5m;
d[1] = 13.5m;
d[2] = -12.5m;
d[3] = -13.5m;
for (int i = 0; i < d.Length; i++)
{
Console.WriteLine("{0}", d[i]);
Console.WriteLine("Math.Round(値) ="
+ Math.Round(d[i]));
Console.WriteLine("Math.Round(値, MidpointRounding.ToEven) ="
+ Math.Round(d[i], MidpointRounding.ToEven));
Console.WriteLine("Math.Round(値, MidpointRounding.AwayFromZero) ="
+ Math.Round(d[i], MidpointRounding.AwayFromZero));
Console.WriteLine("Math.Floor(値) ="
+ Math.Floor(d[i]));
Console.WriteLine("Math.Ceiling(値) ="
+ Math.Ceiling(d[i]));
Console.WriteLine("Decimal.Round(値) ="
+ Decimal.Round(d[i]));
Console.WriteLine("Decimal.Round(値, MidpointRounding.ToEven) ="
+ Decimal.Round(d[i], MidpointRounding.ToEven));
Console.WriteLine("Decimal.Round(値), MidpointRounding.AwayFromZero="
+ Decimal.Round(d[i], MidpointRounding.AwayFromZero));
Console.WriteLine("Convert.ToInt32(値) ="
+ Convert.ToInt32(d[i]));
Console.WriteLine("(int)(値) ="
+ (int)(d[i]));
Console.WriteLine("----------");
}
実行結果
12.5
Math.Round(値) =12
Math.Round(値, MidpointRounding.ToEven) =12
Math.Round(値, MidpointRounding.AwayFromZero) =13
Math.Floor(値) =12
Math.Ceiling(値) =13
Decimal.Round(値) =12
Decimal.Round(値, MidpointRounding.ToEven) =12
Decimal.Round(値), MidpointRounding.AwayFromZero=13
Convert.ToInt32(値) =12
(int)(値) =12
----------
13.5
Math.Round(値) =14
Math.Round(値, MidpointRounding.ToEven) =14
Math.Round(値, MidpointRounding.AwayFromZero) =14
Math.Floor(値) =13
Math.Ceiling(値) =14
Decimal.Round(値) =14
Decimal.Round(値, MidpointRounding.ToEven) =14
Decimal.Round(値), MidpointRounding.AwayFromZero=14
Convert.ToInt32(値) =14
(int)(値) =13
----------
-12.5
Math.Round(値) =-12
Math.Round(値, MidpointRounding.ToEven) =-12
Math.Round(値, MidpointRounding.AwayFromZero) =-13
Math.Floor(値) =-13
Math.Ceiling(値) =-12
Decimal.Round(値) =-12
Decimal.Round(値, MidpointRounding.ToEven) =-12
Decimal.Round(値), MidpointRounding.AwayFromZero=-13
Convert.ToInt32(値) =-12
(int)(値) =-12
----------
-13.5
Math.Round(値) =-14
Math.Round(値, MidpointRounding.ToEven) =-14
Math.Round(値, MidpointRounding.AwayFromZero) =-14
Math.Floor(値) =-14
Math.Ceiling(値) =-13
Decimal.Round(値) =-14
Decimal.Round(値, MidpointRounding.ToEven) =-14
Decimal.Round(値), MidpointRounding.AwayFromZero=-14
Convert.ToInt32(値) =-14
(int)(値) =-13
----------
続行するには何かキーを押してください . . .
いわゆる四捨五入にならない部分を赤で書きました。
解説
Math.Round(値) = (A)
Math.Round(値, MidpointRounding.ToEven) = (A)
Math.Round(値, MidpointRounding.AwayFromZero) = 四捨五入
Math.Floor(値) = (B)
Math.Ceiling(値) = (C)
Decimal.Round(値) = (D)
Decimal.Round(値, MidpointRounding.ToEven) = (D)
Decimal.Round(値, MidpointRounding.AwayFromZero)= 四捨五入
Convert.ToInt32(値) = 縮小変換
(int)(値) = キャスト
(A) 指定された値に最も近い遇数値(JIS丸め)
中央値(n.5)の場合は指定された値に最も近い偶数値(銀行丸め・JIS丸め)
(B) 指定された数より小さい、最大の整数(切捨て)
(C) 指定された数より大きい、最小の整数(切り上げ)
(D) 指定した小数点以下の桁数への丸め(JIS丸め)
結論
いわゆる四捨五入をしたいのであれば、
Math.Round(値, MidpointRounding.AwayFromZero)
Decimal.Round(値, MidpointRounding.AwayFromZero)
を使いましょう。
キャストはとんでもないことになってますね。(全部赤色だし)
→ 端数を捨てる(Fix()と同じ)結果になるため、四捨五入には不適ですね。