VB的浮點數處理

來源:互聯網
上載者:User
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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.