電子書籍の厳選無料作品が豊富!

ExcelのVBAで単精度浮動点小数(以下、小数)を16進数に直すためにコードを書いています。
頭の中では、小数→整数部分と小数点以下に分解→2進数→16進数に変換処理という流れはできています・・・

そこで、10進数を2進数に直すために、2で割らないといけません。そのあたりの処理をどのように書いたら良いか分かりません。
桁数の関係で、DEC2BIN関数は使えないので


以下、今できているコードを貼り付けます。
=====================================================
Dim inte As Integer
Dim nsign As String
Dim float32, pint As Double
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' 小数を整数部分+小数点以下部分に分解
''
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
If InStr(float32, ".") = 0 Then
inte = Mid(float32, 1)
Else
inte = Mid(float32, 1, (InStr(float32, ".") - 1))
pint = "0" & Mid(float32, (InStr(float32, ".")))
End If

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' 小数の正負判定(2進数の時使う)
''
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
If float32 >= 0 Then ' float32が0以上かどうか
nsign = 0 ' Trueなら 0
Else
nsign = 1 ' Falseなら 1
End If
=====================================================

以上ですが、よろしくお願いします。

質問者からの補足コメント

  • うーん・・・

    処理の流れを言葉で書けてもVBAでの表し方が ?? になりやすいので、VBAのコードも書いていただけると助かります。

      補足日時:2018/08/26 13:13
  • うーん・・・

    Do~Loop文でとりあえず整数部分の2進数変換はできました。
    あとは、小数点以下の2進数変換です・・・
    ======================
    Dim inte As Integer
    Dim ww, ws As String
    int2 = Abs(inte)
    Do
    ww = int2 \ 2
    If ww = 0 Then
    ws = (int2 Mod 2) & ws
    Exit Do
    End If
    ws = (int2 Mod 2) & ws
    int2 = ww
    Loop
    ======================

      補足日時:2018/08/26 15:18

A 回答 (4件)

>可能なら2進数も欲しいのですが、16進数から2進数にするか・・・


No3です。
2進数に変換する機能を追記しました。
以下、実行結果です。
00
00
20
C0
00000000
00000000
00100000
11000000
------------------------------------------
Option Explicit

Type F32
d As Single
End Type

Type B4
d(4) As Byte
End Type

Public Sub dump()
Dim data1 As Single
Dim in_data As F32
Dim out_data As B4
Dim i As Long
data1 = -2.5
in_data.d = data1
LSet out_data = in_data
For i = 0 To 3
Debug.Print ByteToHex(out_data.d(i))
Next
For i = 0 To 3
Debug.Print ByteToBit(out_data.d(i))
Next
End Sub
Private Function ByteToHex(ByVal data As Byte) As String
ByteToHex = Hex$(data)
If Len(ByteToHex) < 2 Then
ByteToHex = "0" & ByteToHex
End If
End Function

Private Function ByteToBit(ByVal data As Byte) As String
Dim i As Long
Dim str As String
str = ""
For i = 1 To 8
str = (data Mod 2) & str
data = data \ 2
Next
ByteToBit = str
End Function
    • good
    • 0
この回答へのお礼

ユーザー関数って便利ですね!何とか期待した値を返すことができるようになりました。
ありがとうございました。

お礼日時:2018/08/26 17:42

IEEE754 で定義される単精度浮動小数点数(32ビット)の内部表現を16進数でそのまま見たいということと解釈しました。


以下のようにしてください。
例では、-2.5の値の単精度浮動小数点数(32ビット)の内部表現を16進数で表示しています。
結果は、イミディエイトウィンドウに
00
00
20
C0
と表示されます。従って、内部表現は、00 00 20 C0 になります。
下記URLにC言語で-2.5の内部表現を求める方法が書いてあります。-2.5の内部表現は C0 20 00 00になります。
https://qiita.com/nia_tn1012/items/d26f0fc993895 …
私が提示した方法では、00 00 20 C0 となっていますが、これはリトルエンディアンの為です。
もし、C0 20 00 00のような結果を望むなら、
i=0 to 3 を i = 3 to 0 に変えてください。
------------------------------------
Option Explicit
Type F32
d As Single
End Type
Type B4
d(4) As Byte
End Type
Public Sub dump()
Dim data1 As Single
Dim in_data As F32
Dim out_data As B4
Dim i As Long
data1 = -2.5
in_data.d = data1
LSet out_data = in_data
For i = 0 To 3
Debug.Print ByteToHex(out_data.d(i))
Next
End Sub

Private Function ByteToHex(ByVal data As Byte) As String
ByteToHex = Hex$(data)
If Len(ByteToHex) < 2 Then
ByteToHex = "0" & ByteToHex
End If
End Function
    • good
    • 1
この回答へのお礼

コード付での返信ありがとうございます。
教えて頂いたコードは確かに1発で16進数にできますね。シート上の値を取得して、シート上に変換結果を返す所まで確認しました。
可能なら2進数も欲しいのですが、16進数から2進数にするか・・・

お礼日時:2018/08/26 16:26

例えば円周率 x = 2 pi = 6.2831... を例に取ります。



1.sign(x) = 1

2. log2(x) = 2.65 > 2 であるから整数部の桁数3
3. x > 2^2 であるから整数部3桁目は 1
4. pi - 1 * 2^2 > 2^1 であるから整数部2桁目は1
5. pi - 1 * 2^2 - 1 * 2^1 < 2^0 であるから整数部1桁目は 0
これで x の整数部の2進数が、(符号ビットを除いて)110 と決まる。

6. 小数部を y = x - 6 とする。
7. y < 2^(-1) であるから小数部1桁目は 0
8. y - 0 * 2^(-1) > 2^(-2) であるから小数部2桁目は 1
9. y - 0 * 2^(-1) - 1 * 2^(-2) < 2^(-3) であるから小数部3桁目は 0

こんな感じで、2進数を何ビットで表現するか分かりませんが、仕様で決めた桁数まで小数部の計算を繰り返します。
    • good
    • 0
この回答へのお礼

もともと与えられる小数が IEEE754 binary32 に則った数なので、2進数でいうと32bitで表現しないといけないです。
言葉では何となく理解できるんですが、コードではどのように書き表していくといいのかピンと来ず・・・

お礼日時:2018/08/26 13:19

いきなりコードを書くのではなくて、処理の流れを言葉で書いてみましょう。



元の数を x とするとき
1. x の符号の正負によって、2進数の符号ビットを決定
2. x = 2^p と表現する時の p の値から、2進数としての整数部の桁数が決定
3. 小数部は、桁が許す限り割り算を繰り返す。

ざっくり書いたけれど、これをもっと詳細に文字にしてみましょう。
    • good
    • 1
この回答へのお礼

mabuterolさんの処理の流れとは違いますが・・・
3.以降で止まっている感じです。

元の数をxとする。
1.x を整数部と小数部に分解。
2.x の符号で正負を決定。
3.整数部を商が0になるまで2で割り続ける。
4.3.の余りを逆順で結合。
5.小数部の小数点以下が0になるまで掛け算。
6.5の整数部分を結合。
7.例外処理を入れる(循環小数)
8.2,4,6を結合し、16進数に直す。

お礼日時:2018/08/26 11:55

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています