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

Math.Ceilingの挙動

  • 題名: Math.Ceilingの挙動
  • 著者: こう
  • 日時: 2008/04/30 20:25:39
  • ID: 21960
  • この記事の返信元:
    • (なし)
  • この記事への返信:
  • ツリーを表示
環境/言語:[XPsp2 VB2005 .NET Framework 2.0]
分類:[.NET]

不可思議な現象に困っています。

Dim D1 As Double = 1.1#
Dim D2 As Double = 100#
Dim D3 As Double = D1 * D2
MsgBox(D3.ToString)
'110と表示
MsgBox(Math.Ceiling(D3).ToString)
'111と表示

うちの環境だけでしょうか。
それとも .Net Framework のバグなんでしょうか。

やりたかったことは、double型変数を、小数点第3桁を切り上げて、
小数点2桁の文字列を得ようとして、

Private Function Ceil3(ByVal D As Double) As String
Return Format(CDbl(Math.Ceiling(D * 100.0#)) / 100.0#, "#0.00")
End Function

としたのですが、D=1.1だと、1.11が返ってきてしまうのです。

とりあえず他の方法で逃げてもいいのですが、
何かよい方法はないでしょうか?
double 型で 1.1 は正確には記述できません。近似値にしかなりません。それに 100 を掛けても当然誤差が生じます。詳しくは浮動小数点数を検索してください。
D3 を直接 ToString したときに 110 と表示されるのは、誤差が表示できないほど小さいので適当に丸められているってだけです。

誤差を許容できない場合は Decimal を使ってください。
■No21962に追記(Hongliangさんの記事)
> double 型で 1.1 は正確には記述できません。近似値にしかなりません。

浮動小数点数では、データを「2進数」として保持するためですね。


追加情報として、過去ログのこのあたりとか。
http://dobon.net/vb/bbs/log3-18/10633.html
  • 題名: Re[3]: Math.Ceilingの挙動
  • 著者: こう
  • 日時: 2008/05/01 8:08:51
  • ID: 21970
  • この記事の返信元:
  • この記事への返信:
    • (なし)
  • ツリーを表示
Hongliangさん、魔界の仮面弁士さん、ありがとうございました。

Decimalで対応することにしました。
解決済み!

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