- 締切済み
Excel Vbaの関数Intの機能について
Excel Vbaでの関数Intの機能について教えてください ある特定の値についての処理が私の予想に反した動きをします。私の理解が浅いと思うのですがその理由が分かりません。 Vbaでプロシジャーを作ってみました。ともに小数0.3を10倍し、 その値とIntの値を比較しています。コードの違いは(1)と(2)です。 Public Sub Test1() Dim dblNum1 As Double, dblNum2 As Double dblNum1 = 0.2 dblNum1 = dblNum1 + 0.1 ……(1) dblNum2 = dblNum1 * 10 Debug.Print "Int(dblNum2) = " & Int(dblNum2); " : dblNum2 = " & dblNum2 Debug.Print "差(Test1):" & dblNum2 - Int(dblNum2) End Sub Public Sub Test2() Dim dblNum1 As Double, dblNum2 As Double dblNum1 = 0.3 ' dblNum1 = dblNum1 + 0.1 ……(2)コメントにしています dblNum2 = dblNum1 * 10 Debug.Print "Int(dblNum2) = " & Int(dblNum2); " : dblNum2 = " & dblNum2 Debug.Print "差(Test2):" & dblNum2 - Int(dblNum2) End Sub 実行結果は次のようになりました。 Test1の結果 Int(dblNum2) = 3 : dblNum2 = 3 差(Test1):4.44089209850063E-16 Test2の結果 Int(dblNum2) = 3 : dblNum2 = 3 差(Test2):0 差(Test1)がなぜ0にならないのか不思議な気がします(当たり前なのかな?)。 0.8についても同様な結果になります。 その他の値0.1 ~ 0.9では、私の予想通り、差(Test1)、差(Test2)ともに0になります。 ネットなどで検索したら、浮動小数点の扱いに関係がありそうだなのかなぐらいは想像できるのですが具体的な仕組みはよく分かりません。 この疑問に至った背景について、説明します。 Int関数の機能については特段興味はなかったのですが、「有限小数の小数点以下の桁数を調べる関数」を作るのに利用していました。その関数では、なぜか特定の小数についてはうまく機能しませんでした。調べていくうちに上記のような現象に気づきました。 話がそれて厚かましいお願いになりますが、「有限小数の小数点以下の桁数を調べる関数」のコーディングの例を教えていただけないでしょうか。私が作った関数は以下のようになります。これについてもアドバイスをいただければ大変助かります。 Public Function FiniteDCPlace(dblR As Double, intMax As Integer) As Integer '機能:小数点以下の何桁の有限小数になるか、その桁数を調べる。 '引数:dblRは小数、intMax は調べる最大の桁数 ただしintMaxは7以下の値 '戻り値:小数点以下の桁数がintMax以下の有限小数の場合、その桁数 ' それ以外は「-1」 Dim i As Integer Dim dblNum As Double If intMax > 7 Then FiniteDCPlace = -1 Exit Function Else 'No Ope End If dblNum = dblR FiniteDCPlace = -1 For i = 0 To intMax Debug.Print "Int(dblNum) = " & Int(dblNum) & " : dblNum = " & dblNum Debug.Print "差(FiniteDCPlace):" & dblNum - Int(dblNum) If Int(dblNum) = dblNum Then FiniteDCPlace = i Exit For Else dblNum = dblNum * 10 FiniteDCPlace = -1 End If Next End Function 次のプロシジャーでチェックしました。 小数 0.028 のとき3ではなく、-1を返します。 Private Sub testFiniteDCPlace() Dim intNum As Integer Dim dblNum As Double Dim i As Integer dblNum = 0.028 ‘予想外の結果になる intNum = FiniteDCPlace(dblNum, 7) Debug.Print dblNum & " の桁数 : " & intNum dblNum = 0.027 ‘予想通りの結果になる 3になる intNum = FiniteDCPlace(dblNum, 7) Debug.Print dblNum & " の桁数 : " & intNum End Sub ちなみに、環境はOS Widows10 、Excel2013 です。 以上よろしくお願いします。 質問の内容を書いてください
- みんなの回答 (4)
- 専門家の回答
みんなの回答
- real beatin(@realbeatin)
- ベストアンサー率82% (174/211)
- real beatin(@realbeatin)
- ベストアンサー率82% (174/211)
- real beatin(@realbeatin)
- ベストアンサー率82% (174/211)
- dogs_cats
- ベストアンサー率38% (278/717)
お礼
realbeatin 様 お礼が遅くなりました。 質問内容がタイトルから外れたものになったにもかからわらず、丁寧に回答をいただきありがとうございます。小数点以下の桁数を求める関数3つともうまくいきました。「小数点の位置」版が一番分かりやすいように思いました。自分もMSDNの「データ型のトラブルシューティング(Visual Basic)-浮動小数点式での比較が等しくならない」を参考に修正版を作り、うまくいきました。 今回の回答で勉強させてもらったこと。 >二進数【浮動小数点数】を十進数【小数点数】Variant/Decimalに変換してから・・・ そもそも、Decimal(10進数型)を知りませんでした。(はるか昔に勉強した?) 型変換の関数についてもほとんど知識がありませんでした。 どの場面でどのように使えばいいのかの経験を積んでいきたいと思います。 >それから、前回のご質問の時から気になっていたのですが、 >セルに表示されている(数値ではなくて)数字(文字列)を取得する >range.Text プロパティの扱い方を確認しておくと、 >もしかしたら何かの役に立つこともあるのかも知れません。 セルに表示されている(数値)を計算処理しないのであれば(文字列)として扱うという発想が全くありませんでした。桁数を求める関数でも同様でした。数値の場合はrange.Value プロパティしか使っていませんでした。 今回の質問のきっかけは、生徒が演習した結果を自動採点する教材を作る中での疑問でした。「表示形式->小数点以下の3位の設定」の判定で正解と生徒答案のNmberFormatLocalを比較していました。計算結果がたまたま有限小数3位のセルがあり、生徒が書式設定をしなくて「標準/G」のままで、チェックがうまくいきませんでした(チェックから「標準/G」を外していた)。授業の課題が「書式設定」の場合は、従来通りNumberFormatLocalを利用する。 印刷結果を重視(見た目がすべて)する場合はrange.Textを利用することにしました。 浮動小数点の精緻な数値計算については特に興味はなっかたのですが、疑問をすぐに解消したくて、本来の目的からそれた質問をしてしまいました。 realbeatin 様 3度もお世話になりました。 3回の質問とも「そのことが分かってそれが、なんやねん。そもそもお前は何がしたいねん。」と突っ込まれそうな内容にも関わらず丁寧に対応していただき本当にありがとうございました。