[覚書]使い方に要注意

切り捨ては、Math.Floorで行う。decimalであれば、decimal.Truncateも有り。
var intVal = Math.Floor(123.45m);
似たようなメソッドで、Convert.ToInt32なんてものがあるが、あれはあまり使わない方が良い。
Convert.ToInt32 メソッド (Decimal)より抜粋

近似値の 32 ビット符号付き整数に丸められた value。 value が 2 つの整数の中間にある場合は、偶数が返されます。たとえば、4.5 は 4 に変換され、5.5 は 6 に変換されます。

とある。試してみると、
var intVal1 = Convert.ToInt32(4.5m);//intVal1 = 14
var intVal2 = Convert.ToInt32(44.5m));//intVal2 = 44
勘違いしてたんだけど、あくまで「中間」にあるときで、そうじゃないと四捨五入っぽい動きになる。
var intVal3 = Convert.ToInt32(44.56m);//45
うん。紛らわしいな。
スポンサーサイト
当サイトは基本をすっ飛ばしてます。基本文法等は、@ITをどうぞ
カテゴリー: C# | コメント: 1 | トラックバック: 0


この記事へのコメント

会計用の「偶数丸め」ですね
まだC#の経験半年の私がコメントするのは、ちょっと
図々しいかも・・・ と、思いつつ、
たまたまこの件については学生時代に数値計算の
授業の時に習ったので、補足説明させてください。
小数点第一位以下の値がランダムにバラけているときは、
単純な四捨五入によって生じる丸め誤差はプラスにも
マイナスにも均等に発生しうるので、
四捨五入した値を合計しても、丸め誤差は
打ち消し合う(可能性が高い)と、考える
ことができます。
一方、実際の計算では、整数の合計値を2で割るとか4で割るなど、
小数点第一位がぴったり0.5になる場合が結構あります。
このとき、一般的な四捨五入だと0.5は必ず切り上げられますから
そういう「整数でないときの半端は、0.5である可能性が高い」
数字の集まりを小数第一位で四捨五入して合計すると、
切り上げの丸め誤差のほうが過剰になって累積誤差が
無視できなくなります。
これは、「端数がビッタリ0.5のときは、1/2の確率で
切り上げか切り捨てにする」ようにして、誤差をプラスマイナイスの両方向にバラけさせれば改善できますが。。。

確率1/2といっても、乱数でどちらかを選んだりしたら(統計学的には乱数のほうが望ましいのですが)、
集計するたびに微妙に数値が変わってしまうので、
金銭計算では非常に困ったことになります。
そこで、金銭計算のルールとして、端数が
ぴったり0.5のときは、直近の偶数に切り上げ
または切り捨てをするということになっている
のです。
四捨五入したい値の整数の第一位をみて、切り捨てにするか切り上げにするかを変えることで、
四捨五入の誤差が±0.5にどちらにもなりうるように
決めているわけです。
たぶんこれは、コンピュータが登場する以前からの
知恵なんでしょうね。

コメントの投稿

非公開コメント


サイドバー背後固定表示サンプル

当ブログに書かれたソースコードは流用自由です。

バグ、スペルミス等はありうる事です。

ご利用の際は自己責任でお願いしますm(_ _)m