【问题标题】:Converting big-endian into little-endian and vice-versa in VBA在VBA中将big-endian转换为little-endian,反之亦然
【发布时间】:2011-02-09 15:31:05
【问题描述】:

我的机器是 little-endian(Intel 字节顺序)。我需要以 Motorola/IEEE 字节顺序(“big-endian”)读取包含 16 位有符号整数数据的二进制文件,然后进行一些计算,最后将生成的 integer 数据写入 big-endian 二进制文件。

如何在 VBA 中执行上述操作,即将大端转换为小端,反之亦然?

原因是,我正在处理 NASA Shuttle Radar Topography Mission 数据 (HGT file format)。

【问题讨论】:

    标签: vba excel endianness


    【解决方案1】:

    通过使用简单的按位逻辑。

    Public Function SwapBytes(ByVal i As Integer) As Integer
      Dim b1 As Byte, b2 As Byte
    
      b1 = i And &HFF
    
      If i And &H8000 Then
        b2 = ((i And &H7F00) / 256) Or &H80
      Else
        b2 = (i And &HFF00) / 256
      End If
    
      If b1 And &H80 Then
        SwapBytes = (b1 And &H7F) * 256 Or b2 Or &H8000
      Else
        SwapBytes = b1 * 256 Or b2
      End If
    
    End Function
    

    好吧,由于 VBA 的限制,并不是那么简单。 不过,我相信这会比调用两次 CopyMemory 函数快得多。

    【讨论】:

      【解决方案2】:

      这是一个可以帮助您入门的子程序:

      Public Sub ProcessData()
        Dim inputFileName As String
        Dim outputFileName As String
        Dim wordCount As Integer
        Dim i As Integer
        Dim msb As Byte
        Dim lsb As Byte
        Dim unsignedWord As Long
        Dim word As Integer
      
        inputFileName = "C:\Input.bin"
        outputFileName = "C:\Output.bin"
      
        wordCount = FileLen(inputFileName) / 2
      
        Open inputFileName For Binary Access Read As #1
        Open outputFileName For Binary Access Write As #2
      
        For i = 1 To wordCount
          Get #1, , msb
          Get #1, , lsb
      
          unsignedWord = CLng(msb) * 256 + lsb
          If unsignedWord > 32768 Then
            word = -CInt(65536 - unsignedWord)
          Else
            word = CInt(unsignedWord)
          End If
      
          ' Do something with each word.
          word = -word
      
          If word < 0 Then
            unsignedWord = 65536 + word
          Else
            unsignedWord = word
          End If
          msb = CByte(unsignedWord / 256)
          lsb = CByte(unsignedWord Mod 256)
      
          Put #2, , msb
          Put #2, , lsb
        Next
      
        Close #1
        Close #2
      End Sub
      

      【讨论】:

        【解决方案3】:

        这是一个简单的 ASCII 转换:

        Public Function SwapLong(Data As Long) As Long
        
            Const Sz As Integer = 3
            Dim Bytes(Sz) As Byte
            Dim n As Integer
            Dim HexStr As String
            Dim SwpStr As String
        
            HexStr = Right("00000000" + Hex(Data), 2 * (Sz + 1))
            SwpStr = vbNullString
        
            For n = 0 To Sz
                SwpStr = SwpStr + Mid(HexStr, (Sz - n) * 2 + 1, 2)
            Next n
        
            SwapLong = CLng("&h" + SwpStr)
        
        End Function
        
        Public Function SwapInt(Data As Integer) As Integer
        
            Const Sz As Integer = 1
            Dim Bytes(Sz) As Byte
            Dim n As Integer
            Dim HexStr As String
            Dim SwpStr As String
        
            HexStr = Right("0000" + Hex(Data), 2 * (Sz + 1))
            SwpStr = vbNullString
        
            For n = 0 To Sz
                SwpStr = SwpStr + Mid(HexStr, (Sz - n) * 2 + 1, 2)
            Next n
        
            SwapInt = CInt("&h" + SwpStr)
        
        End Function
        

        【讨论】:

          猜你喜欢
          • 2022-06-10
          • 1970-01-01
          • 1970-01-01
          • 2014-03-05
          • 2020-12-01
          • 1970-01-01
          • 1970-01-01
          • 2019-06-30
          • 2018-10-23
          相关资源
          最近更新 更多