質問

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

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

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

これも試してみましたが、99.97も返されました:

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

不足しているもの

ありがとう!

役に立ちましたか?

解決

あなたは実際には中間点にいません。 MidpointRounding.ToEven は、番号が 99.965 の場合、つまり99.96500000 [etc。]、 then の場合、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);
}

他のヒント

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

C:\temp>ipy
IronPython 2.6 Beta 2 (2.6.0.20) on .NET 2.0.50727.4927
Type "help", "copyright", "credits" or "license" for more information.
>>> import clr
>>> from System import Math, 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
>>>

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

対象にいくつかの光を当てた結果は次のとおりです。

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ではありません。

値が2つのケースの間にある場合にのみ、中間点の丸めが考慮されます。

あなたの場合、「5」ではなく「535 ...」なので、中点より大きく、ルーチンは.96になります。期待どおりの動作を得るには、MidpointRounding.ToEvenを使用して3番目の小数点まで切り捨てる必要があります。

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

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

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

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

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

P.S。
Floor ceiling の反対で、数値に最も近い整数を返します。
したがって、 9996.535789 の上限は 9997 です。
どちらも小数点以下を丸める とは異なり、実際には数値に最も近い整数を返します。そのため、 rounding を使用したときに 99.97 を取得していました。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top