10

Math.Roundで期待する結果が表示されません。

return Math.Round(99.96535789, 2, MidpointRounding.ToEven); // returning 99.97

MidpointRounding.ToEvenを理解しているように、1000分の5の位置にある5は、出力が99.96になるはずです。そうではありませんか?

私もこれを試しましたが、99.97も返されました:

return Math.Round(99.96535789 * 100, MidpointRounding.ToEven)/100;

私は何が欠けていますか

ありがとう!

4

8 に答える 8

27

あなたは実際には中点にいません。MidpointRounding.ToEven番号が99.965、つまり99.96500000 [etc。]の場合、99.96になることを示します。Math.Roundに渡す数値はこの中間点を超えているため、切り上げています。

数値を99.96に切り捨てる場合は、次のようにします。

// this will round 99.965 down to 99.96
return Math.Round(Math.Truncate(99.96535789*1000)/1000, 2, MidpointRounding.ToEven);

そしてねえ、これは一般的なケースのために上記を行うための便利な小さな関数です:

// This is meant to be cute;
// I take no responsibility for floating-point errors.
double TruncateThenRound(double value, int digits, MidpointRounding mode) {
    double multiplier = Math.Pow(10.0, digits + 1);
    double truncated = Math.Truncate(value * multiplier) / multiplier;
    return Math.Round(truncated, digits, mode);
}
于 2009-09-14T18:12:20.893 に答える
10

中間点自体にいる場合、つまり99.965の場合にのみ、99.96に丸められます。

C:\ temp> ipy
.NET2.0.50727.4927上のIronPython2.6Beta 2(2.6.0.20)
詳細については、「help」、「copyright」、「credits」、または「license」と入力してください。
>>>インポートclr
>>>システムインポート数学、MidpointRoundingから
>>> Math.Round(99.9651、2、MidpointRounding.ToEven)
99.97
>>> Math.Round(99.965、2、MidpointRounding.ToEven)
99.96
>>> Math.Round(99.9649、2、MidpointRounding.ToEven)
99.96
>>> Math.Round(99.975、2、MidpointRounding.ToEven)
99.98
>>>
于 2009-09-14T18:12:31.887 に答える
5

値は、最下位桁MidpointRoundingが正確に5である値を丸めようとしている場合にのみ機能します。つまり、値は目的の結果を取得するためのものである必要があります。ここではそうではないので、単に標準の丸めメカニズムを観察しているだけです。詳細については、MSDNページを参照してください。99.965

于 2009-09-14T18:13:49.453 に答える
4

このテーマに光を当てた結果は次のとおりです。

Math.Round(99.96535789, 2, MidpointRounding.ToEven); // returning 99.97
Math.Round(99.965, 2, MidpointRounding.ToEven);      // returning 99.96
Math.Round(99.96500000, 2, MidpointRounding.ToEven); // returning 99.96

中点は正確に5です...535789ではなく、499999ではありません。

于 2009-09-14T18:14:08.860 に答える
0

中間点の丸めは、値が2つのケースの間にある場合にのみ調べられます。

あなたの場合、それは「5」ではなく、「535 ...」なので、中点より大きく、ルーチンは.96になります。期待する動作を得るには、小数点以下第3位まで切り捨ててから、MidpointRounding.ToEvenを使用して丸める必要があります。

于 2009-09-14T18:13:36.377 に答える
0

Math.Round'小数値を指定された小数桁数に丸めます。' 99.96500000,2を99.96に丸め、99.96500001を99.67に丸める場合。値全体を丸めます。

于 2009-09-14T18:16:02.710 に答える
0

それが私なら、それはMath.Round()あなたが達成しようとしていることではないので、私は使用しません。

これは私がすることです:

double num = 99.96535789;
double percentage = Math.Floor(100 * num) / 100;  

これははるかに読みやすく、数学的なアプローチです。
数に、を掛けると100、今は9996.535789
次に、丸めとは明らかに異なるフロアを作成して、数値に最も近い最小の整数を返し、を取得します9996
次に、除算し100て必要なを取得します99.96

PS
Floorceilingの反対であり、数値に最も近い最大の整数を返します。
だから、の天井は9996.535789です9997どちらも小数点なしの四捨五入
と は異なります。小数点なしでは、数値が小さいか大きいかにかかわらず、数値に最も近い整数が実際に返されます。そのため、丸めを使用したときに取得していました。99.97

于 2010-11-20T00:26:46.223 に答える
0

ソリューションを共有してくれたDanTaoに感謝しますが、4.485などの数値では常に間違った結果が得られるため、この問題を解決するために作成した方法を共有しています:)

public static decimal TruncateThenRound(decimal value, int? degits = 0, MidpointRounding? midpointRounding = MidpointRounding.ToEven)
    {
        var multiplier = Convert.ToDecimal(Math.Pow(10.0, degits.Value));

        var unwantedDecimals = (value * multiplier) - Math.Truncate(value * multiplier);

        var truncated = Math.Truncate(value * multiplier) / multiplier;

        bool roundUp = midpointRounding == MidpointRounding.ToEven ? Math.Truncate(unwantedDecimals * 10) > 5m : Math.Truncate(unwantedDecimals * 10) >= 5m;

        return roundUp ? truncated + (1 / multiplier) : truncated;
    }
于 2021-07-07T08:52:51.660 に答える