- ベストアンサー
Visual Basicで2進数を10進数に変換するプログラムの問題点と指摘
- Visual Basicで任意の数字を入力し、Len関数とMid関数を使って2進数を10進数に変換するプログラムがうまく動作しない。
- コードの問題点は、変数aのデータ型が間違っていたことと、Forループの条件が正しく設定されていなかったこと。
- 正しいコードは、変数aをString型にし、Forループの条件をLen(a) - 1 To 0 Step -1とする必要がある。
- みんなの回答 (7)
- 専門家の回答
質問者が選んだベストアンサー
変数aはstring型がいい。 mid関数の引数のLen(a)はおかしい、ここはiとすべきでは 変数bはどこかで初期化した方がいい。 b += 2 ^ (i - 1) この式はおかしい、LSBからビットを 判定しているのに、iがMSBからになっている。 1と0以外の文字が来た場合の処理を入れたほうがいい。 全体的にプログラムを見なおしたほうがいい。
その他の回答 (6)
- shut0325
- ベストアンサー率40% (490/1207)
No.3です。 一応確認ですが、VBであって、VBAではないのですよね? その上で、学習のため、あえてLenやMid関数を使って2進→10進変換をすると。 その場合、下記のような感じになります。そうじゃないときはどちらにも変換の関数やクラスがありますので、そっちを使ってください。 ※入力された文字が半角の0か1だけかどうかのチェックやエラー処理は省略しています。 Dim BinT As String = TextBox1.Text Dim TLen As Integer = Len(BinT) Dim Ans As Integer = 0 For i = 0 To TLen - 1 Ans += Mid(BinT, TLen - i, 1) * (2 ^ i) Next Label3.Text = Ans Mid関数で文字列の右から順に数値を取り出し、それに 2^(桁-1)を乗算、それを加算、という繰り返しです。 2^0=1なので、iは0スタートとし、そのためにストップは桁数(文字数)-1としています。
- Hayashi_Trek
- ベストアンサー率44% (366/818)
こんな感じ Dim ans As Integer Dim bit As Integer Dim i As Integer ans = 0 For i = 1 To Len(TextBox1.Text) bit = val(Mid(TextBox1.Text, i, 1)) ans = 2 * ans + bit Next i Label3.Text = Cstr(ans)
- kmee
- ベストアンサー率55% (1857/3366)
頭で考えて混乱するのなら、設計図を書いてみましょう。 例えば a="101100" を変換しようとすれば aの1文字目:1 → 1 * 2^5 aの2文字目:0 → 0 * 2^4 aの3文字目:1 → 1 * 2^3 aの4文字目:1 → 1 * 2^2 aの5文字目:0 → 0 * 2^1 aの6文字目:0 → 0 * 2^0 となります。 ここで、「aのk文字目」と「2^m」のkとmの関係をよく見ましょう。 一定の法則に従ってますよね? ここで、 k=i としてループを作ったら、mはiを使ってどう表現できるか。 あるいは m=iだったらkはiを使ってどう表わせるか、考えてみましょう。 別解 1 * 2^5 + 0 * 2^4 + 1 * 2^3 + 1 * 2^2 + 0 * 2^1 + 0 * 2^0 =(((((0*2+1) * 2 + 0) * 2 + 1) * 2 + 1 ) * 2 + 0 ) * 2 + 0 です。何か法則が見えませんか?
- tom04
- ベストアンサー率49% (2537/5117)
No.2です。 >lenとmidを利用しないとだめなのです というコトですので、あまりスマートではありませんが、 Dim i As Long, str As String, myVal myVal = 0 For i = Len(TextBox1) To 1 Step -1 str = Mid(TextBox1, i, 1) If Val(str) > 1 Then MsgBox "2進数を入力" With TextBox1 .Value = "" .SetFocus End With Exit Sub Else myVal = myVal + 2 ^ (Len(TextBox1) - i) * Val(str) End If Next i Label3 = myVal こんな感じではどうでしょうか?m(_ _)m
- shut0325
- ベストアンサー率40% (490/1207)
No.1の方がおっしゃるとおりだとおもいますが、補足として、、、 for文内ではif文を入れない方がスマートです。 該当の桁の文字を整数に変換すれば(必ず0か1)if文にする必要がなくなります。 0は何乗しようと0ですから、1か0かの判別は必要ありません。
補足
>for文内ではif文を入れない方がスマートです。 ありがとうございます。 理解出来た部分を直したら Dim a As String Dim b As Integer Dim i As Integer a = Val(TextBox1.Text) b=0 For i = Len(a) To 1 Step -1 Mid(a, Len(i), 1) = "1" Then b += 2 ^ (i-1) Next Label3.Text = b End Sub こうでしょうか?
- tom04
- ベストアンサー率49% (2537/5117)
こんにちは! せっかくコードをお考えのようですが、 質問ではユーザーフォームのLabel3に「10進数表示」させたいだけのようですので、 単純にワークシート関数を利用してはダメですか? Dim i As Long, str As String, myFlg As Boolean For i = 1 To Len(TextBox1) str = Mid(TextBox1, i, 1) If Val(str) > 1 Then myFlg = True Exit For End If Next i If myFlg = True Then MsgBox "2進数を入力" With TextBox1 .Value = "" .SetFocus End With Else Label3 = WorksheetFunction.Bin2Dec(Val(TextBox1)) End If のような感じで・・・ ※ 入力間違いがないのであれば >Label3 = WorksheetFunction.Bin2Dec(Val(TextBox1)) の1行だけで大丈夫です。 上記コードはTexobox1に2進数以外に入力があった場合を考慮してのコードにしていますので、 若干長くなっています。m(_ _)m
補足
すみません、メゾットを使わずlenとmidを利用しないとだめなのです。
補足
>変数aはstring型がいい。 >mid関数の引数のLen(a)はおかしい、ここはiとすべきでは >変数bはどこかで初期化した方がいい。 ありがとうございます。 b += 2 ^ (i - 1) この式はおかしい、LSBからビットを 判定しているのに、iがMSBからになっている。 これはどこを直せばいいのでしょうか。申し訳ありません。