結果は 806603.77 になるはずですが、なぜ 806603.8 になるのでしょうか?
float a = 855000.00f;
float b = 48396.23f;
float res = a - b;
Console.WriteLine(res);
Console.ReadKey();
結果は 806603.77 になるはずですが、なぜ 806603.8 になるのでしょうか?
float a = 855000.00f;
float b = 48396.23f;
float res = a - b;
Console.WriteLine(res);
Console.ReadKey();
A float
( とも呼ばれるSystem.Single
) の精度は、10 進数で約7桁です。あなたのres
差には、8桁の有効数字が必要です。したがって、 a には十分な精度がないことが予想されfloat
ます。
添加:
追加情報: 806,000 (806,000) 付近float
で、小数部分に 4 ビットしか残っていません。そのためres
、どちらかを選択する必要があります
806603 + 12/16 == 806603.75000000, and
806603 + 13/16 == 806603.81250000
理想的な結果に最も近い最初のものが選択されます。ただし、これらの値は両方とも、"806603.8"
呼び出し時と同じように出力されますToString()
(Console.WriteLine(float)
呼び出します)。ToString
ジェネラルコールでは、最大 7 桁の有効数字が表示されます。2 つの浮動小数点数が標準の書式設定で同じように出力される場合でも、それらが異なることを明らかにするには、次のように書式文字列を使用します"R"
。
Console.WriteLine(res.ToString("R"));
Because float
has limited precision (32 bits). Use double
or decimal
if you want more precision.
Decimalを盲目的に使用するだけでは十分ではないことに注意してください。
Odedによって投稿されたリンクを読む:すべてのコンピューター科学者が浮動小数点演算について知っておくべきこと
次に、使用する適切な数値タイプを決定します。
Decimalを使用するだけで正確な結果が得られるという考えに陥らないでください。常にそうとは限りません。
次のコードを検討してください。
Decimal d1 = 1;
Decimal d2 = 101;
Decimal d3 = d1/d2;
Decimal d4 = d3*d2; // d4 = (d1/d2) * d2 = d1
if (d4 == d1)
{
Console.WriteLine("Yay!");
}
else
{
Console.WriteLine("Urk!");
}
10進数の計算が正確である場合、そのコードは「Yay!」と出力するはずです。d1はd4と同じでなければならないからですよね?
まあ、そうではありません。
また、10進数の計算は、2進数の計算よりも数千倍遅いことに注意してください。これらは、非通貨計算(たとえば、ピクセルオフセットや速度などの物理的なもの、または超越数などを含むものの計算)に常に適しているとは限りません。