6

数値を小数点以下第 1 位に丸めようとしていますが、さまざまな MidpointRounding オプションを考慮すると、うまく機能しているようです。ただし、その数値が四捨五入に算術的に影響する小数点以下の桁数が連続している場合、問題が発生します。

例:

0.10.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.10.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最初の10進数に丸めようとするともちろん失敗します(これは である必要があります0.2が、結果は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: 無数の乗算と減算を行わずに数字を列挙する方法がわかりません。

簡単に言えば、それを行うための最良の方法は何ですか?

4

4 に答える 4

20

Math.Round()正しく動作しています。

中間点の丸めの考え方は、中間の数値の半分を切り上げ、残りの半分を切り捨てるというものです。したがって、0.1 ~ 0.2 の数値の場合、半分は 0.1 に丸め、半分は 0.2 に丸める必要があります。これら 2 つの数値の中間点は 0.15 であるため、切り上げのしきい値です。0.146 は 0.15 より小さいため、切り捨てて 0.1 にする必要があります。

                    Midpoint
0.10                  0.15                  0.20
 |----------------|----|---------------------|
                0.146
       <---- Rounds Down
于 2010-03-25T11:16:02.913 に答える
15

ここで何を達成しようとしているのかわかりません。0.149 を小数点第 1 位に四捨五入すると 0.2 ではなく 0.1 になります。

于 2010-03-25T11:10:41.133 に答える
6

丸めは反復プロセスではなく、1 回だけ丸めます。

したがって、10 進数 1 桁に丸められた 0.1460.1 です。

あなたはこれをしません:

0.146 --> 0.15
0.15 -->  0.2

これを行うだけです:

0.146 --> 0.1

それ以外の場合は、次のとおりです。

0.14444444444444446

も 0.2 に丸められますが、そうではありませんし、そうすべきではありません。

于 2010-03-25T11:23:35.847 に答える
5

丸めの「エラー」を複雑にしないでください。これがあなたがやろうとしていることです。

小数点以下 1 桁にする場合は、 .146切り捨てて .1 にする必要があります。

最初に .15 に丸め、次に再び .2 に丸めると、丸め誤差が少なくなるのではなく、増えるだけです。

于 2010-03-25T11:16:52.320 に答える