C#で
double tmp = 3.0 * 0.05;
tmp = 0.1500000000000002
これにはお金が関係しています。値は実際には $0.15 ですが、システムは $0.16 に切り上げる必要があります。0.151 はおそらく 0.16 に切り上げられるべきですが、0.15000000000000002 ではありません。
正しい数値を取得する方法を教えてください (つまり、0.15、または小数が十分に大きい場合は 0.16)。
固定小数点変数タイプ、または Decimal のような 10 進浮動小数点タイプを使用します。浮動小数点数は常にいくらか不正確であり、2 進数の浮動小数点表現は、基数 2 との間で変換するときに別の不正確さのレイヤーを追加します。
エンタープライズ アプリケーション アーキテクチャのパターンで、Martin Fowler は Money 抽象化の使用を推奨しています。
http://martinfowler.com/eaaCatalog/money.html
ほとんどの場合、彼は通貨を扱うためにそれを行いますが、精度も扱います。
この Google ブックの検索結果でその一部を見ることができます。
データ型decimal
はうまく機能し、おそらくあなたの選択です。
ただし、過去に、固定小数点整数を使用して最適化された方法でこれを行うことができました。decimal
これは、パフォーマンスが低下し、 の小さな精度誤差を許容できない高性能計算に最適ですfloat
。
から始めて、 と言ってInt32
、半分に分割します。前半は整数部分、後半は小数部分です。16 ビットの符号付き整数と 16 ビットの小数精度が得られます。たとえば、16:16 固定小数点としての 1.5 は として表され0x00018000
ます。または、必要に応じてビットの配分を変更します。
固定小数点数は通常、他の整数と同様に追加/サブ/マルチ/ディビジョンできますが、オーバーフローを避けるためにマルチ/ディビジョンを少し回避する必要があります。
'decimal' タイプは、このために特別に設計されました