アプリ版:「スタンプのみでお礼する」機能のリリースについて

みなさまこんばんわです。よろしくお願い申し上げます。

VB.NET 2008でFunctionプロシージャを作っています。
その内容は、Double型の値を与えると、その小数点第一位のみをInteger型で返すというものです。

たとえば、3.142を与えると、1を返します。38.98を与えると、9を返します。

これを次のようにコーディングしました。コメントは、39.9を与えたときの動作です。答えは、9を期待しますよね。

-------------------------------------
Function SyosutenWoKaesu(ByVal NyuuryokuSuuchi As Double) As Integer

Dim SyosutenBubun As Double
Dim SeisuuBu As Integer

SeisuuBu = Fix(NyuuryokuSuuchi)
'Fix関数は、入力数値の整数部を返すので、39をInteger型で返します

SyosutenBubun = NyuuryokuSuuchi - CDbl(SeisuuBu)
'データ型をDouble型に変換し、引き算。39.9-39なので、0.9という答えを期待しますが、実際は、0.899999999999999が返ってきます

SyosutenBubun = SyosutenBubun * 10
SyosutenWoKaesu = Fix(SyosutenBubun)
'10倍した数の整数部なので、8を返します。困ります。

End Function
-------------------------------------

なんで 39.9 - 39 が0.9じゃないんでしょうか?
しかも、10.9など、少ない数字だと、きちんと演算されます。また、100.9などだと、途中、0.900000000000006などの数値になるんですけど、答えはきちんと9を出力します。

また、小数点第一位が9以外だと、うまくいくんです。
ちなみに、CDbl関数を使わなくても同じでした。また、-演算子の代わりに、Mod演算子(割り算の余りを返す演算子)を使っても全く同じでした。


なんでこんな不正確な演算結果になるんでしょうか?
あるいは、別のもっとスマートな方法がありますでしょうか?


よろしくお願い申し上げます。

A 回答 (1件)

浮動小数点の演算による誤差でしょうね



小数第1位の数値を返すのなら
Function SyosutenWoKaesu(ByVal NyuuryokuSuuchi As Double) As Integer
  dim n as Integer
  n = ( NyuuryokuSuuchi * 10 ) mod 10
  return n
End Function
でうまくいきそうですが ・・・
    • good
    • 1
この回答へのお礼

ご回答いただき、ありがとうございます!!

やはり、小数点はどうしても誤差が出るようです。Single型にすると、いっそう誤差が大きいです。

で、ご回答いただいたコード・・・
目から鱗でした!
無理に小数点演算をするんじゃなくて、いったん10倍して1のくらいにまで引き上げてから、1桁目を求めるとは・・・これはイイです!!!

コードを書いてみましたが、やはり小数点の演算にならないので、問題なく動きました! ありがとうございました!

実際は、小数点第2位以下があることを考慮し、最後にFix関数で小数点をすべて切り捨て、整数だけにしてInteger型で返すようにすれば、問題となった誤差は一切発生せず、上手く動いています。


完全に解決しました。ありがとうございました!!!!

お礼日時:2009/04/15 22:57

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!