• ベストアンサー

演算について

演算についてよくわからないのですが、 Dim KeiA As Integer = 80 Dim KeiB As Integer = 70 Dim KeiC As Double = 61.08 Dim KeiD, KeiE As Double KeiD = KeiA - KeiC KeiE = KeiB - KeiC デバック時に自動変数で見てみると KeiDは18.92 KeiEは8.9200000000000017 になってしまいます。なぜKeiEは8.92ではないんでしょうか。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

小数の演算誤差です。 61.08は、内部で0.6108*10^2と表現されています。 2進数では、0.5=1/2、0.25=1/4、0.125=1/8 ... となるので、 0.6108≒0.500000000000 + ← 1/2     0.062500000000 + ← 1/16     0.031250000000 + ← 1/32     0.015625000000 + ← 1/64     0.000976562500 + ← 1/1024     0.000244140625 + ← 1/4096    =0.610595703125 の様に表現されます(仮数部8ビットの場合)。したがって、最後まで上手くまとまらなかったところが誤差になってしまいます。

sakasakasa
質問者

補足

なんとなくわかりました。なんか除算の時注意しなければとどっかで覚えたんでした(^^;今一番困っているのは、実はそのKeiDやKeiEを足して、また他の数字で割ったりといろいろその後も計算をしていきたいのですが、最初の時点で誤差が出てしまって、最終的に違う結果になってしまうんです。どうしたらよいでしょうか。KeiCを100倍して、すべての型はInteger型に書き直して最後の最後で100で割るという風にすればよいのでしょうか。

その他の回答 (4)

回答No.5

質問とは関係ありませんが、 >Dim KeiD, KeiE As Double と記述すると、「KeiD」は Variant型になります。 Doubl型で宣言したいのであれば、下記の様に記述しましょう! Dim KeiD As Double Dim KeiE As Double

sakasakasa
質問者

補足

当方、VB.NET2002でした。よくわかってないですがVariant型はないのかも知れません。私はVariant自体知りませんでした(>_<)

回答No.4

話がそれているかもしれませんが、、、 倍精度(Double)でなければならないのですよね? 単精度(Single)であれば、誤差が発生しませんでした。

sakasakasa
質問者

補足

DoubleをすべてSingleに直しデバッグしてみましたが、KeiD=18.9199982、KeiE=8.919998でした。ますます混乱してきました笑

  • ymmasayan
  • ベストアンサー率30% (2593/8599)
回答No.3

> 最初の段階で誤差が出てしまって > そういうときはどうしたらよいでしょうか Doubleであれば充分有効数字がありますので誤差を無視して計算を続け、 最後に必要な桁数でまるめをすればいいでしょう。 小数点3桁を取るなら1000倍して0.5を足してINTをとって1000で割るとか。

sakasakasa
質問者

お礼

最後にだけ丸めだけをすればよかったんですね。途中でMath.Round関数で少数第2までにしてもうまく行かず困ってました。有効桁数の意味がよくわかってませんでした…。

  • ymmasayan
  • ベストアンサー率30% (2593/8599)
回答No.2

KeiDとKeiEで様子が違うので戸惑っておられるのでしょうね。 Doubleということは浮動小数点に直されます。 Integerも計算時にDoubleに変換されます。 このとき、有限桁で表せないと打切り誤差が出ます。 80と61.08ではその打切り誤差がたまたま打ち消しあったのでしょう。 単精度なら正しく表示されると思います。

sakasakasa
質問者

補足

そうなんです(>_<)実は、Ano.1の方の補足質問にも書きましたが、 今一番困っているのは、そのKeiDやKeiEを足して、また他の数字で割ったりといろいろその後も計算をしていきたいのですが、最初の段階で誤差が出てしまって・・・。そういうときはどうしたらよいでしょうか。すいません質問ももっと詳しく書けばよかったです。

関連するQ&A

  • データ型変換

    String型のデータをInteger型の変数に入れたいのでが・・・。 '変数の宣言 Dim DataTable(2, 5) As String Dim made As Integer 'データ型変換 made = CInt(DataTable(1, 0)) このようにしたのですが、実行すると 『実行時エラー '13'  型が一致しません』 と表示され、デバックしてみるとココ↓ made = CInt(DataTable(1, 0)) が黄色くなります。 どうしたら上手く型変換ができるのでしょうか? ちなみに、VB6.0です。

  • 変数

    Dim トータル As Integer トータル = 200 Dim 変数1(トータル) As Integer Dim 変数2(トータル) As Integer Dim 変数3(トータル) As Integer Dim 変数4(トータル) As Integer ※変数1~4に同じ数の変数(クローン??)を用意したいのですがエラーがでます。 このような使い方は出来ないのでしょうか? なお、VB上ではローマ字で使っています。 変数は6個ぐらいあり 毎回変えるのは面倒なので・・・ (スパイラルモデル方式??といっても使うのは私自信ですが・・・)

  • Function 構文のなかに変数をいれたい(VBA)

    お願いします。 エクセルVBAにて 下記のようなFunction構文内に変数を設定する方法を 教えてください。 この中で k以外にも a = Sheets("sheet1").Range("E27") b = Sheets("sheet1").Range("E27") この変数を扱いたいのですが。 もしかして他にもfunction構文が必要でしょうか。 Function data(k As Double) Dim sum As Double Dim ct As Integer Dim keisu As Integer Dim a As Double Dim b As Double a = Sheets("sheet1").Range("E27") b = Sheets("sheet1").Range("E27")  以下 略

  • 小数点の引き算が不正確

    みなさまこんばんわです。よろしくお願い申し上げます。 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演算子(割り算の余りを返す演算子)を使っても全く同じでした。 なんでこんな不正確な演算結果になるんでしょうか? あるいは、別のもっとスマートな方法がありますでしょうか? よろしくお願い申し上げます。

  • アクセス(2003)のVBAでビット演算方法

    エクセルのマクロではビット演算ができましたが、アクセスではどのような方法があるのでしょうか? where in 文で値の自動生成も考えられますが、VBやVCでアドインも可能でしょうか教えてください。 '*********** Excel VBA Bit 演算 ************ Private Sub Boln() Dim MyBln As Boolean Dim Object1 As Range Dim Object2 As Range Set Object1 = Range("B11") Set Object2 = Range("B12") MyBln = Object1 And Object2 MsgBox MyBln End Sub '*********** Excel VBA Bit 演算 ************ 以上、宜しくお願いします。

  • VBAで変数定義を変更する方法

    Data_Typeという変数の中に文字列doubleが入っていたら、 AIyyという変数をdoubleで定義、 longが入っていたらlongで定義するというプログラムを作りたいのですが If Data_Type = "double" Then Dim AIyy As Double ElseIf Data_Type = "long" Then Dim AIyy As Long End If と書くと、定義が重複しているというエラーが表示されてうまくいきません。 これはどうすれば良いでしょうか? それと一度integerで定義した変数をlongなどに定義を変更したい場合どのようにすれば良いでしょうか?

  • 初歩的な質問ですいません

    Dim i As Integer この場合、iを整数の変数として定義する。 だと思うのですが、 Dim i(10000) As Integer この場合どういう意味ですか? 教えていただきたいです。

  • VBのfunctionの引数について

    2の Double型と 3の Single型のように送る側と受け取る側の変数の型が 違ってもよいのでしょうか?プログラムはそのまま実行できたのですが・・・・。 Public Class Form1 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim koku As Integer Dim san As Integer Dim rika As Integer Dim ave As Double------------------------------------1 koku = Val(TextBox1.Text) san = Val(TextBox2.Text) rika = Val(TextBox3.Text) ave = (koku + san + rika) / 3 Label5.Text = Round(ave)-------------------------------2 End Sub Private Function Round(ByVal sngvalue As Single-----3) As Integer Dim intvalue As Integer intvalue = Int(sngvalue + 0.5) Return intvalue End Function End Class

  • VBAの変数変換のことです

    VBAの変数変換のことです 整数変数=実数変数や実数変数=整数変数でCIntやCSng関数を使わないでOKでしょうか? Dim VAR(20) As Single '単精度浮動小数点数型 (Single) Dim IVARO(20) As Integer '整数型 (Integer) Dim IVAROC(20) As Integer '整数型 (Integer) IVARO(NCD) = VAR(NCD) 'Single to Integer IVAROC(NCD) = CInt(VAR(NCD)) 'Single to Integer これで、IVARO(NCD)とIVAROC(NCD)には同じ値が入っているのですが、 整数=実数でCInt関数を使わないで整数にする構文はOKでしょうか?

  • Excel VBA の文字列連結演算子 &

     変な質問で申し訳ないのですが・・・  Excel VBA の文字列連結演算子 & は   Dim St As String   Dim No As Integer   St = "来年は"   No = 2020   Range("A1").Value = St & No とすれば St & No は確かに "来年は2020" という文字列になります。本来ならば   St & Str(No) とすべきだと思いますが、なぜこんな仕様にしたのでしょうか?  また、ベースとなった VB.NET も同じ仕様なのでしょうか?