DOBON.NET DOBON.NETプログラミング掲示板過去ログ

単純な計算で

環境/言語:[XP,VB.NET,NET Framework2.0.50727 ]
分類:[.NET]

いつもお世話になっております。

少数切り捨のロジックで試行錯誤している際に不思議?な現象に出くわしました。
単純な乗算ですが、値によってとんでもない端数値になるのは何故でしょう?
またこれは.netでは回避出来ないのでしょうか?

 例 2.50*100 → 250.0
2.51*100 → 250.99999999999997
2.52*100 → 252.0
2.53*100 → 252.99999999999997
2.54*100 → 254.0
2.55*100 → 254.99999999999997
2.56*100 → 256.0
2.57*100 → 257.0



よろしくお願いいたします。
  • 題名: Re[1]: 単純な計算で
  • 著者: きいよ
  • 日時: 2008/09/17 15:38:51
  • ID: 23012
  • この記事の返信元:
  • この記事への返信:
    • (なし)
  • ツリーを表示
ハマリ人さん

データ型は、何を使われていますか?

Decimal型にて計算されたらいかがでしょう。
  • 題名: Re[1]: 単純な計算で
  • 著者: 魔界の仮面弁士
  • 日時: 2008/09/17 21:07:52
  • ID: 23015
  • この記事の返信元:
  • この記事への返信:
    • (なし)
  • ツリーを表示
■No23010に返信(ハマリ人さんの記事)
> 値によってとんでもない端数値になるのは何故でしょう?

浮動小数点型(Single, Double)は、データを2進小数で管理しているためです。

10進小数の場合、1÷3 を表現しきれない事はわかりますよね。
有限桁数では「0.3333」などいう誤差を含んだ値になってしまいますので。

そして 2 進小数の場合、1÷10 等を表現しきれません(10÷2 なら表せますが)。
そのため先ほどの計算では、僅かな誤差が含まれてしまったわけです。


> またこれは.netでは回避出来ないのでしょうか?
既に回答が付いていますが、10進数を主眼においた計算処理においては、
Decimal 型の利用を検討してみてください。
(その分、メモリ効率/計算効率は悪くなりますけれども)


' これは、「Double型2.51」×「Integer型100」を意味します。
' 計算結果は、Double 型です。
x = 2.51 * 100

' R は、Double 型を意味するリテラルの型文字であり、
' これは、「Double型2.51」×「Double型100」を意味します。
' 計算結果は、Double 型です。
a = 2.51R * 100.0R

' # は、Double 型を意味する識別子の型文字であり、
' これは、「Double型2.51」×「Double型100」を意味します。
' 計算結果は、Double 型です。
b = 2.51# * 100.0#

' D は、Decimal 型を意味するリテラルの型文字であり、
' これは、「Decimal型2.51」×「Decimal型100」を意味します。
' 計算結果は、Decimal 型です。
c = 2.51D * 100D

' @ は、Decimal 型を意味する識別子の型文字であり、
' これは、「Decimal型2.51」×「Decimal型100」を意味します。
' 計算結果は、Decimal 型です。
d = 2.51@ * 100@


Single や Double の場合、数値データを「小数」として管理していますが、
Decimal 型は、「整数」のまま管理しているため、誤差を抑える事ができます。
これは、96桁の2進数であり、10 進数換算でいえば「2の96乗 - 1」すなわち
79,228,162,514,264,337,593,543,950,335 が最大値となります。

DOBON.NET | プログラミング道 | プログラミング掲示板