質問
double a = 18.565
return Math.Round(a,2)
.. 18.57を返します。
他のすべての数について、私は銀行家の丸めを試したことを試みました。たとえば、Math.Round(2.565,2)が2.56を返しました。
なぜそれが起こるのか、何が起こるのですか?それはエラーですか、それとも銀行家の丸めについて何かが欠けていますか?
ありがとう..
解決
マシューが言ったように、18.565を正確に表現することはできません。使用される実際の値は18.56500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023681640625(使用されています DoubleConverter)、これは明らかに中途半端を超えています。今、私はそれをこっそり感じています 時折 Math.Round
ある値を考慮します 実際に 中途半端なポイントを超えて、しかし、正確に正確に表現できるほど中途半端なポイントに近いです で その点。しかし、私はそれが適用されている状況を説明するドキュメントを見たことはありませんが、この場合は明らかにそれが起こっていません。私はそれに頼りたくありません。
もちろん、丸い値でさえ正確に18.57ではありません。 It's actually 18.57000000000000028421709430404007434844970703125.
基本的に、あなたが本当に、10進数を正確に表現することを本当に気にしているなら、あなたは使用する必要があります decimal
. 。それは単なる観点だけではありません Math.Round
- それは、浮動小数点値の処理のあらゆる側面に行きます。
それか します 適切な値を与えます Math.Round
, 、 もちろん:
decimal m = 18.565m;
Console.WriteLine(Math.Round(m, 2)); // Prints 18.56
他のヒント
18.565は、ダブルとして正確に表すことはできません。したがって、バイナリ表現はわずかに高くなるため、切り上げます。 Decimalを使用する場合:
decimal a = 18.565m;
return Math.Round(a,2)
それは正確に表すことができ、あなたはこの問題を抱えていません。
私の推測では、FP表現は、実際には5ではないことを意味します。 FPの危険性!
ただし、これは正常に機能します。
decimal a = 18.565M; // <===== decimal
var s = Math.Round(a, 2);
Doubleは浮動小数点値です。そのため、18.565として書いている場合、実際には18.5650000000000000000000000000000000001のようなものであるため、ミッドポイント以上のものです。