.NETで「正しい」算術丸めを行う方法はありますか? / C#
-
22-09-2019 - |
質問
私はそれがうまく動作するようです異なるMidpointRoundingオプションを考慮すると、小数点第一位の場所だとに番号を丸めるしようとしています。その数は算術丸めに影響を与えるsunsequent小数点以下の桁数を持っているときに問題が発生しても。
例:
それが動作0.1
、0.11..0.19
と0.141..0.44
でます:
Math.Round(0.1, 1) == 0.1
Math.Round(0.11, 1) == 0.1
Math.Round(0.14, 1) == 0.1
Math.Round(0.15, 1) == 0.2
Math.Round(0.141, 1) == 0.1
しかし0.141..0.149
が0.1
に丸めるべきであるが0.146..0.149
と、それは常に、0.2
を返します:
Math.Round(0.145, 1, MidpointRounding.AwayFromZero) == 0.1
Math.Round(0.146, 1, MidpointRounding.AwayFromZero) == 0.1
Math.Round(0.146, 1, MidpointRounding.ToEven) == 0.1
Math.Round(0.146M, 1, MidpointRounding.ToEven) == 0.1M
Math.Round(0.146M, 1, MidpointRounding.AwayFromZero) == 0.1M
私はこの問題のアドレスという機能を思い付くことを試み、それがこのような場合に適していますが、それは小数点第一の0.144449
あるべき桁(が、結果だとあなたはラウンドすなわち0.2
しようとした場合、もちろん、それはglamorously失敗0.1
。)(恐らくMath.round(と仕事をしない)のいずれか。)
private double "round"(double value, int digit)
{
// basically the old "add 0.5, then truncate to integer" trick
double fix = 0.5D/( Math.Pow(10D, digit+1) )*( value >= 0 ? 1D : -1D );
double fixedValue = value + fix;
// 'truncate to integer' - shift left, round, shift right
return Math.Round(fixedValue * Math.Pow(10D, digit)) / Math.Pow(10D, digit);
}
私は解決策が4、その後のラウンドアップ、または他のラウンドダウンより大きい最初の値を見つけ、すべての数字を列挙するだろうと仮定します。問題1:ばかげたようだ、問題2:私は、乗算とsubtractiosの無数ずに数字を列挙するか見当がつかない。
。ロングストーリーショート:?
それを行うための最善の方法は何ですか解決
Math.Round()
が正しく動作されます。
、あなたがに丸めているところを超えた小数第1桁を超え探す必要がありません。あなたは最寄りの10分の丸めされている場合、あなたは決して小数点以下二桁目を越えて見る必要はありません。
中間点の丸めとの考えはこれらの間の数値の半分では切り上げる必要があり、半分は切り捨てなければなりません。だから、0.1と0.2の間の数値のため、それらの半分は0.1に丸める必要があり、半分は0.2に丸める必要があります。それは切り上げのためのしきい値ですので、これらの2つの数の間の中間点は、0.15です。 0.146したがって、それは0.1に切り捨てる必要があり、0.15未満である。
Midpoint
0.10 0.15 0.20
|----------------|----|---------------------|
0.146
<---- Rounds Down
他のヒント
私はあなたがここで達成しようとしているものを得ることはありません。 0.149は、0.1小数点の位を四捨五入がのではない0.2
丸めは反復的なプロセスではありません、あなたのラウンドに一度だけます。
1進数字が 0.1
に丸め0.146だからあなたはこれをしません
0.146 --> 0.15
0.15 --> 0.2
あなただけのこの操作を行います
0.146 --> 0.1
それ以外の場合は、以下:
0.14444444444444446
また、ラウンド0.2へのだろうが、それはない、といけない。
丸め「エラー」を試してみて、化合物はありません。あなたがやろうとしているものである。
0.1に0.146 のはずのラウンドダウンあなたは、小数点以下1桁に行くしている場合。
あなただけの多くの丸め誤差を導入し、小さくないています。 0.2に再度、最初の0.15にそれを丸めて