忍者ブログ

16進数を2進数に変換するVBAプログラムでBingと勝負してみた話

2024年01月07日
前回の2進数を10進数に変換する関数とかなり似た内容なんだけど、
16進数を2進数を変換するプログラムも作ってみた。


まず浮かぶやり方は、0~9、A~Fの文字に対する2進数を
IF文等で分岐するやり方。

なんかあんまスマートじゃないし、速度も遅そう。


もう一つは数学的に2で割った商と余りから計算するやり方。

軽く検索をかけたところ、以下のサイトがヒット。

https://vbabeginner.net/convert-hextobin/


16進数をいったん10進数に変換して、
10進数を2進数に変換するという2ステップを踏む方が高速だったとのこと。


上記のリンクの内容を信じて2ステップを踏んで処理する仕様にした。
作ったソースコードがこちら。
' %%%% 16進数から2進数へ %%%%%
Function Hex2BinEx(hex)
    If hex = "" Then
        Hex2BinEx = ""
    Else
        Dim i As Long
        For i = 1 To Len(hex)
            Hex2BinEx = Hex2BinEx & Format(Dec2BinEx(CInt("&H" & Mid(hex, i, 1))), "0000")
        Next i
    End If
End Function
Function Dec2BinEx(strDec As String)
    If strDec = "" Then Dec2BinEx = ""
    
    Dim sBin        As String   '// 2進数文字列
    Dim iRemainder  As Integer  '// 余り
    Dim dDiv        As Long   '// 商
    
    dDiv = Val(strDec)
    
    Do
        iRemainder = dDiv Mod 2
        dDiv = Int(dDiv / 2)
        sBin = CStr(iRemainder) & sBin
        If (dDiv < 2) Then
            If (dDiv = 1) Then
                sBin = CStr(dDiv) & sBin
            End If
            Exit Do
        End If
    Loop
    Dec2BinEx = sBin
End Function


リンクを張った記事の内容をFunctionモジュールにして、不要な初期化等も削除した。

出力される桁数が少なくなる不具合が出たので、
2進数は必ず4桁で出るようにformat関数で指定した。


せっかくなので、Bing AIを使って作ってみたらどうなるか試したところ、
上記のリンクで否定していたselect文で分岐する方法が出てきた。
Function Hex2BinBing(ByVal hex As String) As String
    Dim i As Long
    Dim bin As String
    For i = 1 To Len(hex)
        Select Case UCase(Mid(hex, i, 1))
            Case "0": bin = bin & "0000"
            Case "1": bin = bin & "0001"
            Case "2": bin = bin & "0010"
            Case "3": bin = bin & "0011"
            Case "4": bin = bin & "0100"
            Case "5": bin = bin & "0101"
            Case "6": bin = bin & "0110"
            Case "7": bin = bin & "0111"
            Case "8": bin = bin & "1000"
            Case "9": bin = bin & "1001"
            Case "A": bin = bin & "1010"
            Case "B": bin = bin & "1011"
            Case "C": bin = bin & "1100"
            Case "D": bin = bin & "1101"
            Case "E": bin = bin & "1110"
            Case "F": bin = bin & "1111"
        End Select
    Next i
    Hex2BinBing = bin
End Function
"高速で"というk-ワードを追加してみたけど、
出力される内容は同じで、ビット演算をしているから高速だとか言ってる。

マッピングってビット演算なの・・・?


Bingが折れないので、速度を比較してみた。
0~Fを連結した16進数16文字を1万回2進数に変換して比較してみた。
Sub discTest()
    Dim tictoc As Double
    tictoc = Timer
    Dim i As Long, x
    For i = 1 To 10000
        x = Hex2BinEx("0123456789ABCDEF")
    Next i
    Debug.Print Timer - tictoc, x
    
    tictoc = Timer
    For i = 1 To 10000
        x = Hex2BinBing("0123456789ABCDEF")
    Next i
    Debug.Print Timer - tictoc, x
    
End Sub
Hex2BinEx:自作関数  0.632秒
Hex2BinBing:Bing作成関数  0.143秒


圧倒的に負けた。。。


Bingにソースコードを貼り付けて、どちらが高速動作するか聞いたところ、

以下の2つの関数のどちらが速いかは、実際に実行して比較する必要があります。
ただし、Hex2BinBing関数は、ビット演算子を使用して高速に16進数から2進数に変換するため、
Hex2BinEx関数よりも高速である可能性があります。

とのこと。


ブログのために質問し直したら「実際に実行して比較する」の一点張り。
どうやら、Bingにソースコードを生成させた後に質問したから
自分が提案した方法を推すわけね。

PR
Comment
  Vodafone絵文字 i-mode絵文字 Ezweb絵文字