VB串口通訊中經常會遇到10進位浮點數轉為多位元組Byte資料類型的情況,以及在接收後需轉為10進位浮點數需求。VB有專門的API函數CopyMemory能處理2-10進位浮點數轉換和10-2進位浮點數轉換。下列代碼示範了10進位Single(單精確度浮點型轉為16進位字元顯示的浮點數和其相反運算:Option ExplicitPrivate Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)Private Sub BinToSin_Click() Dim sinStr As String Dim sinSj As Single Dim Buffer(3) As Byte Dim i As Integer sinStr = Text2 For i = 1 To Len(Text2) Step 2 Buffer((7 - i) / 2) = Val("&H" & Mid(sinStr, i, 2)) Next CopyMemory ByVal VarPtr(sinSj), ByVal VarPtr(Buffer(0)), 4 Text3 = sinSjEnd Sub Private Sub SinToBin_Click() Dim i As Integer Dim hexData As String Dim a As Single Dim Buffer(3) As Byte a = Val(Text1) CopyMemory Buffer(0), a, 4 For i = 0 To 3 If Len(Hex(Buffer(i))) = 1 Then hexData = "0" & Hex(Buffer(i)) + hexData Else hexData = Hex(Buffer(i)) + hexData End If Next Text2 = hexDataEnd Sub下列代碼示範了10進位Double(雙精確度浮點型)轉為16進位字元顯示的浮點數和其相反運算:Option ExplicitPrivate Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)Private Sub cmdDoubHex_Click() Dim i As Integer Dim hexData As String Dim a As Double Dim Buffer(7) As Byte a = Val(Text1) CopyMemory Buffer(0), a, 8 For i = 0 To 7 If Len(Hex(Buffer(i))) = 1 Then hexData = "0" & Hex(Buffer(i)) + hexData Else hexData = Hex(Buffer(i)) + hexData End If Next Text2 = hexDataEnd Sub Private Sub cmdHexDec_Click() Dim sinStr As String Dim sinSj As Double Dim bytes(7) As Byte Dim i As Integer sinStr = Text2 For i = 1 To Len(Text2) Step 2 bytes((15 - i) / 2) = Val("&H" & Mid(sinStr, i, 2)) Next CopyMemory ByVal VarPtr(sinSj), ByVal VarPtr(bytes(0)), 8 Text3 = sinSjEnd Sub 但從中無法瞭解它是如何進行運算處理的。以下通過對Single(單精確度浮點型)和Double(雙精確度浮點型)在記憶體的儲存方式進行分析。VB的Single 資料類型 Single(單精確度浮點型)變數儲存為 IEEE 32 位(4 個位元組)浮點數值的形式,它的範圍在負數的時候是從 -3.402823E38 到 -1.401298E-45,而在正數的時候是從 1.401298E-45 到 3.402823E38。Single 的類型宣告字元為驚嘆號 (!)。 在記憶體以32位二進位形式存在: XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX 第1位為符號位 第2-9位為階碼位 第10-32位為2進位小數尾值 即F2 ^ n * 1. XXXXXXX XXXXXXXX XXXXXXXX 其中 F為正號或負號(首為為0正數,首位為1負數 n為2-9位組成的BYTE資料值 XXXXXXX XXXXXXXX XXXXXXXX為尾數 Double(雙精確度浮點型)變數儲存為 IEEE 64 位元(8 個位元組)浮點數值的形式,它的範圍在負數的時候是從 -1.79769313486232E308 到 -4.94065645841247E-324,而正數的時候是從 4.94065645841247E-324 到 1.79769313486232E308。Double 的類型宣告字元是數字記號 (#)。在記憶體以64位二進位形式存在: XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX第1位為符號位 第2-12位為階碼位 第13-64位為2進位小數尾值 即F2 ^ n * 1. XXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX其中 F為正號或負號(首為為0正數,首位為1負數 n為2-12位組成的BYTE資料值 XXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX為尾數 以下代碼是基於前敘述的Single(單精確度浮點型)在記憶體的儲存方式進行分析後作出的2-10進位浮點數運算:Option Explicit Dim hexData As String Dim i As Single Dim bindata As String Dim zs As String * 8 Dim zssz As String Dim xs As String * 23 Dim xs_js() As Double Dim xs_hj As Double Dim sinData As Single Dim sHex As String Dim sBin As String Dim fh As String Private Sub Command1_Click() Dim fh As String sHex = Text1 HexToBin (sHex) fh = Mid(bindata, 1, 1) '取符號 zs = Mid(bindata, 2, 8) '取指數階碼 xs = Mid(bindata, 10, 23) '取2進位小數 xs_hj = 0 zssz = BinToHex(zs) ReDim xs_js(1 To 23) For i = 1 To 23 xs_js(i) = Val(Mid(xs, i, 1)) xs_hj = xs_hj + xs_js(i) / (2 ^ (i)) Next If zs <> "00000000" Then Shape1.FillColor = vbGreen If fh = 0 Then sinData = 2 ^ (Val("&H" & zssz) - 127) * (1 + xs_hj) ElseIf fh = 1 Then sinData = -2 ^ (Val("&H" & zssz) - 127) * (1 + xs_hj) End If ElseIf sHex = "00000000" Then sinData = 0 Shape1.FillColor = vbGreen ElseIf zs = "00000000" Then '處理在0到1.175494351E-38及 Shape1.FillColor = vbRed '0到-1.175494351E-38間的浮點數 If fh = 0 Then sinData = 2 ^ (Val("&H" & zssz) - 126) * xs_hj ElseIf fh = 1 Then sinData = -2 ^ (Val("&H" & zssz) - 126) * xs_hj End If End If Text2 = sinDataEnd Sub Public Function HexToBin(ByVal sHex As String) As String Const s1 = "0000101001101111000", s2 = "0125A4936DB7FEC8" Dim i As Integer, sBin As String sHex = UCase(sHex) For i = 1 To Len(sHex) sBin = sBin & Mid(s1, InStr(1, s2, Mid(sHex, i, 1)), 4) Next i HexToBin = sBin bindata = sBinEnd Function Public Function BinToHex(ByVal sBin As String) As String Const s1 = "0000101001101111000", s2 = "0125A4936DB7FEC8" Dim i As Integer, sHex As String sBin = String(3 - (Len(sBin) - 1) Mod 4, "0") & sBin For i = 1 To Len(sBin) Step 4 sHex = sHex & Mid(s2, InStr(1, s1, Mid(sBin, i, 4)), 1) Next i BinToHex = sHexEnd Function 以下代碼是基於前敘述的Double(雙精確度浮點型)在記憶體的儲存方式進行分析後作出的2-10進位浮點數運算:Option Explicit Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long) Dim hexData As String Dim i As Single Dim bindata As String Dim zs As String '* 8 Dim zssz As String Dim xs As String '* 23 Dim xs_js() As Double Dim xs_hj As Double Dim sinData As Double Dim sHex As StringDim sBin As StringPrivate Sub Command2_Click()Dim fh As StringsHex = Text2HexToBin (sHex)fh = Mid(bindata, 1, 1)zs = Mid(bindata, 2, 11) '取指數xs = Mid(bindata, 13, 52) '取2進位小數xs_hj = 0zs = "0" & zszssz = BinToHex(zs)ReDim xs_js(1 To 52)For i = 1 To 52 xs_js(i) = Val(Mid(xs, i, 1)) xs_hj = xs_hj + xs_js(i) / (2 ^ (i))NextIf zs <> "000000000000" Then Shape1.FillColor = vbGreen If fh = 0 Then sinData = 2 ^ (Val("&H" & zssz) - 1023) * (1 + xs_hj) ElseIf fh = 1 Then sinData = -2 ^ (Val("&H" & zssz) - 1023) * (1 + xs_hj) End IfElseIf sHex = "00000000" Then sinData = 0 Shape1.FillColor = vbGreenElseIf zs = "000000000000" Then '處理在0到2.2250738585072E-308及 Shape1.FillColor = vbRed '0到-2.2250738585072E-308間的浮點數 If fh = 0 Then sinData = 2 ^ (Val("&H" & zssz) - 1022) * xs_hj ElseIf fh = 1 Then sinData = -2 ^ (Val("&H" & zssz) - 1022) * xs_hj End IfEnd IfText3 = sinDataEnd Sub Public Function HexToBin(ByVal sHex As String) As String Const s1 = "0000101001101111000", s2 = "0125A4936DB7FEC8" Dim i As Integer, sBin As String sHex = UCase(sHex) For i = 1 To Len(sHex) sBin = sBin & Mid(s1, InStr(1, s2, Mid(sHex, i, 1)), 4) Next i HexToBin = sBin bindata = sBinEnd Function Public Function BinToHex(ByVal sBin As String) As String Const s1 = "0000101001101111000", s2 = "0125A4936DB7FEC8" Dim i As Integer, sHex As String sBin = String(3 - (Len(sBin) - 1) Mod 4, "0") & sBin For i = 1 To Len(sBin) Step 4 sHex = sHex & Mid(s2, InStr(1, s1, Mid(sBin, i, 4)), 1) Next i BinToHex = sHexEnd Function參考資料:http://zhidao.baidu.com/question/39624959.html
http://zhidao.baidu.com/question/39100439.html
http://topic.csdn.net/u/20080108/14/67783c1e-1a7e-4613-904c-dda5e08a380b.html