こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

プログラミングVisual Basicの質問です。

任意の数字を入力し、Len関数とMid関数を使って2進数を10進数に変換するというプログラムを作っているのですが、うまくいきません。
コードは
Dim a  As Integer
Dim b  As Integer
Dim i  As Integer

a = Val(TextBox1.Text)

For i = Len(a) To 1 Step -1

If Mid(a, Len(a), 1) = "1" Then
b += 2 ^ (i - 1)
End If
Next
Label3.Text = b
   End Sub

上記のものが作ったコードです。
問題点の指摘をよろしくお願いします。

大変申し訳ございませんが、この投稿に添付された画像や動画などは、「BIGLOBEなんでも相談室」ではご覧いただくことができません。 OKWAVEよりご覧ください。

マルチメディア機能とは?

投稿日時 - 2014-07-03 14:54:09

QNo.8663332

すぐに回答ほしいです

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

変数aはstring型がいい。

mid関数の引数のLen(a)はおかしい、ここはiとすべきでは

変数bはどこかで初期化した方がいい。

b += 2 ^ (i - 1) この式はおかしい、LSBからビットを
判定しているのに、iがMSBからになっている。

1と0以外の文字が来た場合の処理を入れたほうがいい。

全体的にプログラムを見なおしたほうがいい。

投稿日時 - 2014-07-03 16:13:14

補足

>変数aはstring型がいい。
>mid関数の引数のLen(a)はおかしい、ここはiとすべきでは
>変数bはどこかで初期化した方がいい。
ありがとうございます。

b += 2 ^ (i - 1) この式はおかしい、LSBからビットを
判定しているのに、iがMSBからになっている。
これはどこを直せばいいのでしょうか。申し訳ありません。

投稿日時 - 2014-07-03 16:48:22

ANo.1

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(7)

ANo.7

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としています。

投稿日時 - 2014-07-04 14:54:01

ANo.6

こんな感じ
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)

投稿日時 - 2014-07-04 01:05:26

ANo.5

頭で考えて混乱するのなら、設計図を書いてみましょう。


例えば
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
です。何か法則が見えませんか?

投稿日時 - 2014-07-04 00:41:02

ANo.4

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

投稿日時 - 2014-07-03 20:18:24

ANo.3

No.1の方がおっしゃるとおりだとおもいますが、補足として、、、

for文内ではif文を入れない方がスマートです。

該当の桁の文字を整数に変換すれば(必ず0か1)if文にする必要がなくなります。
0は何乗しようと0ですから、1か0かの判別は必要ありません。

投稿日時 - 2014-07-03 16:56:33

補足

>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

こうでしょうか?

投稿日時 - 2014-07-03 17:16:49

ANo.2

こんにちは!
せっかくコードをお考えのようですが、
質問ではユーザーフォームの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

投稿日時 - 2014-07-03 16:14:33

補足

すみません、メゾットを使わずlenとmidを利用しないとだめなのです。

投稿日時 - 2014-07-03 16:45:17

あなたにオススメの質問