質問

重複の可能性:
C# の浮動小数点演算が不正確なのはなぜですか?

私はいくつかの数値と C# を扱ってきましたが、次のコード行の結果は予想とは異なる数値になります。

double num = (3600.2 - 3600.0);

num は 0.2 であると予想していましたが、実際には 0.1999999999998181 でした。近いのに異なる小数を生成する理由はありますか?

役に立ちましたか?

解決

それの訳は double は浮動小数点データ型です。

より高い精度が必要な場合は、次の使用に切り替えることができます。 decimal その代わり。

リテラルの接尾辞 decimal は m なので、使用します decimal 算術 (そして、 decimal 結果)コードを次のように書くことができます

var num = (3600.2m - 3600.0m);

を使用するとデメリットがあることに注意してください。 decimal. 。これは、データ型のサイズである 64 ビットとは対照的に、128 ビットのデータ型です。 double. 。これにより、メモリと処理の両方のコストが高くなります。範囲も以前よりもはるかに狭いです double.

他のヒント

理由はあります。

その理由は、double データ型の場合、数値がメモリに格納される方法では、数値 3600.2 を正確に表現できないためです。また、数値 0.2 を正確に表現することもできません。

0.2 はバイナリで無限表現を持ちます。計算を実行するためにメモリまたはプロセッサ レジスタに保存したい場合は、代わりに有限表現の 0.2 に近い数値が保存されます。このようなコードを実行しても明らかではないかもしれません。

double num = (0.2 - 0.0);

これは、この場合、double データ型で数値を表すために使用できるすべての 2 進数が数値の小数部分を表すために使用され (小数部分のみが存在します)、精度が高くなるためです。数値 3600.2 を double 型のオブジェクトに格納すると、整数部分 3600 を表すためにいくつかの桁が使用され、小数部分を表す桁数は少なくなります。精度は低く、実際にメモリに格納される小数部分は 0.2 とは十分に異なるため、double から string への変換後に明らかになります。

タイプを次のように変更します decimal:

decimal num = (3600.2m - 3600.0m);

こちらもお読みください これ.

見る ウィキペディア

もっとうまく説明することはできません。読書を勧めることもできます すべてのコンピュータ科学者が浮動小数点演算について知っておくべきこと. 。または、関連する質問を参照してください スタックオーバーフロー.

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