C#

【C#】Math.Roundで正しく四捨五入する方法

プログラムで演算処理等を実装する際、四捨五入を使う場面は多いと思います。

その際、C#で四捨五入をするなら便利なライブラリあるんじゃないの?と考え、多くの人はMath.Roundメソッドにたどりつくと思います。

そして何も考えずにこのように実装するでしょう。

一見実装は良さそうに見えますね。

でも動かしてみると分かりますが、これでは正しく四捨五入できません。

このプログラムの場合、cには2が入ります。本来は四捨五入されて3が入って欲しいところですが、なぜか2が入るのです。

Math.Roundのデフォルト仕様

上で紹介したような動作になってしまう理由はマイクロソフトのページでMath.Roundの仕様を確認すると理由が分かります。Math.Roundのデフォルトの動作仕様が銀行丸めだからです。

銀行丸め(正式名称:最近接偶数への丸め)とは以下のような丸め方のことを言います。

  • 端数が0.5より小さい場合 ⇒ 切り捨て
  • 端数が0.5より大きい場合 ⇒ 切り上げ
  • 端数が0.5の場合 ⇒ 切り捨てと切り上げで結果が偶数へ近い方へ丸め

端数が0.5ちょうどの場合に通常の四捨五入と動きが異なります。

正しいMath.Roundの実装方法

ではMath.Roundを使う際に正しく四捨五入をしたいならどうすれば良いのかですが、Math.Roundの第2引数にMidpointRounding.AwayFromZeroを指定するだけです。

これで実行するとcには3が入り正しく四捨五入できます。

うっかり第2引数の指定を忘れると銀行丸めになってしまうので、忘れないように気を付けましょう。