【C#】四捨五入

シェアする

  • このエントリーをはてなブックマークに追加

C#で、これまで四捨五入というと何となく

double y = (int)(x + 0.5);

とか、

double y = System.Math.Round(x);

と、行っていたのですが、画像処理で補間処理を行う時に、座標を四捨五入しようとすると、実は自分の思う通りに動いていなかった事に今更ながらに気が付いた...

何はともあれ、int、Roundを使った方法にプラスして、Floorを使って、このようなコード↓

int i;
double x;
double y_int, y_Round, y_Floor;

for (i = -30; i <= 30; i++)
{
    x = i * 0.1;
    y_int = (int)(x + 0.5);
    y_Round = System.Math.Round(x);
    y_Floor = System.Math.Floor(x + 0.5);

    System.Diagnostics.Debug.WriteLine(
        x.ToString() + ", " +
        y_int.ToString() + ", " +
        y_Round.ToString() + ", " +
        y_Floor.ToString()
        );
}

を実行すると、結果は下図のようになります。

C#で四捨五入

これを見ると、intを使った方法では、-1.4~+0.4までがとなり、マイナス側の結果がいまいち。

Roundを使った方法では、一見良さそうなのですが、よ~く結果を見てみると、

0.50に、1.52になっている。

これは銀行型丸め(偶数丸め)と言うらしく、整数の間の値は、最も近い整数に丸めこまれるが、距離が同じ場合は偶数の値を返すとのこと。

(参考)

Math.Round メソッド

http://msdn.microsoft.com/ja-jp/library/wyk4d9cy.aspx

そんな事、全く知らなかった~

という事で、結局はFloorを使った方法が、指定した値以下の最大の整数を返してくれるので、座標を四捨五入したい場合にはFloorを使うと、一番、しっくりきます。

ただし数学には、この結果は四捨五入ではなく、例えば-1.5を四捨五入すると-2になるのが正解のよう。

(追記)
コメントにもあるように、数学的には四捨五入は
double y = System.Math.Round(x, MidpointRounding.AwayFromZero);
とすると良いと思います。

ここでの記事は、あくまで、座標を丸める場合のお話です。

C#へ戻る

関連記事

関連記事

スポンサーリンク

シェアする

  • このエントリーをはてなブックマークに追加

フォローする

コメント

  1. がっちゃん より:

    こんにちは。
    double y = System.Math.Round(x, MidpointRounding.AwayFromZero);
    が一番しっくりくるよう気がします・・・

    • akira より:

      こんばんは。
      確かに普通の四捨五入ならAwayFromZeroを使うのがいいでしょうね。
      とか言いながら、この記事を書くのにいろいろ調べてて、今回、初めてAwayFromZeroの事を知りましたw
      画像処理をやっていると、座標に関して四捨五入をしたい場合が良くあるかと思いますが、AwayFromZeroを使うとー0.5を四捨五入するとー1、+0.5を四捨五入すると+1になりますよね?
      するとー0.5~+0.5の範囲内だけ0になる範囲が他の値よりも若干狭くなるのが気持ち悪くて、座標を四捨五入する場合はFloorの方がしっくりくるという意味合いでした...