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ステップを踏んで処理する仕様にした。
作ったソースコードがこちら。
出力される桁数が少なくなる不具合が出たので、
2進数は必ず4桁で出るようにformat関数で指定した。
せっかくなので、Bing AIを使って作ってみたらどうなるか試したところ、
上記のリンクで否定していたselect文で分岐する方法が出てきた。
出力される内容は同じで、ビット演算をしているから高速だとか言ってる。
マッピングってビット演算なの・・・?
Bingが折れないので、速度を比較してみた。
0~Fを連結した16進数16文字を1万回2進数に変換して比較してみた。
圧倒的に負けた。。。
Bingにソースコードを貼り付けて、どちらが高速動作するか聞いたところ、
以下の2つの関数のどちらが速いかは、実際に実行して比較する必要があります。
ただし、Hex2BinBing関数は、ビット演算子を使用して高速に16進数から2進数に変換するため、
Hex2BinEx関数よりも高速である可能性があります。
とのこと。
ブログのために質問し直したら「実際に実行して比較する」の一点張り。
どうやら、Bingにソースコードを生成させた後に質問したから
自分が提案した方法を推すわけね。
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