進数変換リンク
他のn進数からn進数への変換は以下をご参照ください。
VBAで2進数から8進数へ変換する
VBAで2進数から10進数へ変換する
VBAで2進数から16進数へ変換する
VBAで8進数から2進数へ変換する
VBAで8進数から10進数へ変換する
VBAで8進数から16進数に変換する
VBAで10進数から2進数へ変換する
VBAで10進数から8進数へ変換する
VBAで10進数から16進数へ変換する
VBAで16進数から2進数へ変換する
VBAで16進数から8進数へ変換する
VBAで16進数から10進数へ変換する
2進数から8進数へ変換する考え方
VBAでは2進数を表現するには文字列を扱います。
2進数から8進数に変換するには、2進数文字列を3文字ずつ区切り、その3文字を10進数に変換し、さらにそれを8進数に変換し、区切りごとに出来た8進数を連結させることで完成します。
例:2進数文字列”11010110″を8進数に変換する
右側から3桁ごとに区切ると「”11″(”0″を付与して”011″とする)、”010″、”110″」になります。
プログラムでは3桁固定で区切りたいため事前に左に”0″を必要なだけ追加しています。
3桁区切りの2進数文字列を1文字ずつを10進数に変換します。
“011”の場合は、0×2^2 + 1×2^1 + 1×2^0 → 0×4 + 1×2 + 1×1 → 0 + 2 + 1 → 3
“010”の場合は、0×2^2 + 1×2^1 + 0×2^0 → 0×4 + 1×2 + 0×1 → 0 + 2 + 0 → 2
“110”の場合は、1×2^2 + 1×2^1 + 0×2^0 → 1×4 + 1×2 + 0×1 → 4 + 2 + 0 → 6
これらを連結させて8進数文字列”326″となります。
以下のコードはこの考え方を実装しています。
2進数から8進数に変換する関数
上の説明をコードにした関数が以下になります。
第一引数に変換元となる2進数文字列を指定し、第二引数が変換後の8進数文字列が返却されます。
例えば第一引数に”110″とセットした場合は第二引数に”6″がセットされて関数が終了します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
'// 引数1 (IN) :2進数文字列 '// 引数2 (OUT) :変換後の8進数文字列 Sub BinToOct(a_sBin As String, a_sOct As String) Dim sBin As String '// 2進数文字列 Dim sOct As String '// 8進数文字列 Dim iParts As Integer '// 2進数文字列長ループカウンタ Dim sParts As String '// 2進数文字列を切り出した一部 Dim i As Integer '// ループカウンタ Dim iRemainder As Integer '// 余り Dim iDec As Integer '// 10進数値 Dim iLen As Integer '// 2進数文字列長 '// 引数の2進数文字列が未設定の場合は処理せず抜ける If (a_sBin = "") Then Exit Sub End If sBin = a_sBin '// 2進数文字列の文字数を3で割った余りを取得 iRemainder = Len(sBin) Mod 3 '// 余りがある場合 If (iRemainder > 0) Then '// 不足している"0"を付与 sBin = Left("000", 3 - iRemainder) & sBin End If '// 2進数文字列長を取得 iLen = Len(sBin) '// 2進数文字列を左から3文字ずつループ For iParts = 1 To iLen Step 3 '// 2進数文字列を3文字切り出し sParts = Mid(sBin, iParts, 3) '// 10進数値を初期化 iDec = 0 '// 切り出した文字列を左から順に1文字ずつ10進数値に変換して3文字分を合計する For i = 0 To 2 '// 2進数値×2のn乗の値を加算する iDec = iDec + 2 ^ (2 - i) * CInt(Mid(sParts, i + 1, 1)) Next '// 8進数文字列を連結済みまたは0以外の場合(最初から0が連続している間は連結しない) If (sOct <> "" Or iDec <> 0) Then '// 8進数文字列を連結 sOct = sOct & CStr(Oct(iDec)) End If Next '// ループ処理で8進数文字列が連結されなかった場合(ALL"0"の場合) If (sOct = "") Then sOct = "0" End If '// 引数にセット a_sOct = sOct End Sub |
コードの内容はコメントに大体書いているので分かると思いますが、仕様としていることがあります。
引数の2進数文字列が未設定の場合は処理をせずに関数処理を終わるようにしています。
引数の2進数文字列が”0″と”1″で構成されている前提になっておりエラー処理は入れていません。エラー処理が必要な場合は”0″と”1″だけかどうかのチェックを入れるなどで対応してください。
変換結果の8進数文字列からは先頭に”0″があっても除去しています。たとえば変換結果が”00123″だった場合は”123″として第二引数に戻しています。
使い方
2進数文字列をいくつか持つ配列を作って、ループでBinToOct関数を呼び出し、変換結果をイミディエイトウィンドウに出力するサンプルです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
Sub BinToOctTest() Dim a As String Dim b As String Dim ar ar = Array("1", "10", "11", "100", "101", "110", "111", "1000", "1001") Dim i For i = 0 To UBound(ar) a = ar(i) Call BinToOct(a, b) Debug.Print a & " " & b Next End Sub |
実行結果
1 1
10 2
11 3
100 4
101 5
110 6
111 7
1000 10
1001 11