开发者

Convert MBF Single and Double to IEEE

Follow-Up available: There's a follow-up with further details, see Convert MBF to IEEE.

I've got some legacy data which is still in use, reading the binary files is not the problem, the number format is. All floating point numbers are saved in MBF format (Single and Double). I've found a topic about that on the MSDN boards but that one only deals with Single values. I'd also would like to stay away from API-Calls as far as I can.

Does anyone have a solution for Doubles?

Edit: Just in case somebody needs it, here is the VB.NET Code (it's Option Strict compliant) I ended up with (feel free to convert it to C# and edit it in):

''' <summary>Converts a MBF Single to an IEEE Single</summary>
''' <param name="src">The MBF Single value</param>
''' <returns>The converted IEEE Single value</returns>
''' <remarks>Here can find some further information about this topic: http://en.wikipedia.org/wiki/Microsoft_Binary_Format http://support.microsoft.com/kb/140520</remarks>
Public Shared Function MTIS(ByVal src As Single) As Single
    Return MTIS(BitConverter.GetBytes(src), 0)
End Function

''' <summary>Converts a MBF Single to an IEEE Single</summary>
''' <param name="src">The source array</param>
''' <param name="startIndex">The start index at which the Single starts</param>
''' <returns>The converted IEEE Single value</returns>
''' <remarks>Here can find some further information about this topic: http://en.wikipedia.org/wiki/Microsoft_Binary_Format http://support.microsoft.com/kb/140520</remarks>
Public Shared Function MTIS(ByVal src() As Byte, ByVal startIndex As Integer) As Single
    Dim mbf(3) As Byte
    Dim ieee(3) As Byte

    Array.Copy(src, startIndex, mbf, 0, 4)

    If mbf(3) <> 0 Then
        Dim sign As Byte = mbf(2) And ToByte(&H80)
        Dim exp As Byte = mbf(3) - ToByte(2) ' -1-128-127 '

        ieee(3) = ieee(3) Or sign
        ieee(3) = ieee(3) Or exp >> 1
        ieee(2) = ieee(2) Or exp << 7
        ieee(2) = ieee(2) Or mbf(2) And ToByte(&H7F)
        ieee(1) = mbf(1)
        ieee(0) = mbf(0)
    End If

    Return BitConverter.ToSingle(ieee, 0)
End Function


''' <summary>Converts a MBF Double to a IEEE Double</summary>
''' <param name="src">The MBF Double value</param>
''' <returns>The converted IEEE Double value</returns>
''' <remarks>Here can find some further information about this topic: http://en.wikipedia.org/wiki/Microsoft_Binary_Format http://support.microsoft.com/kb/140520</remarks>
Public Shared Function MTID(ByVal src As Double) As Double
    Return MTID(BitCo开发者_StackOverflownverter.GetBytes(src), 0)
End Function

''' <summary>Converts a MBF Double to a IEEE Double</summary>
''' <param name="src">The source array</param>
''' <param name="startIndex">The start index at which the Double starts</param>
''' <returns>The converted IEEE Double value</returns>
''' <remarks>Here can find some further information about this topic: http://en.wikipedia.org/wiki/Microsoft_Binary_Format http://support.microsoft.com/kb/140520</remarks>
Public Shared Function MTID(ByVal src() As Byte, ByVal startIndex As Integer) As Double
    Dim mbf(7) As Byte
    Dim ieee(7) As Byte

    Array.Copy(src, startIndex, mbf, 0, 8)

    If mbf(7) <> 0 Then
        Dim sign As Byte = mbf(6) And ToByte(&H80)
        Dim exp As Int16 = mbf(7) - 128S - 1S + 1023S

        ieee(7) = ieee(7) Or sign
        ieee(7) = ieee(7) Or ToByte(exp >> 4 And &HFF)
        ieee(6) = ieee(6) Or ToByte(exp << 4 And &HFF)

        For i As Integer = 6 To 1 Step -1
            mbf(i) <<= 1
            mbf(i) = mbf(i) Or mbf(i - 1) >> 7
        Next
        mbf(0) <<= 1

        For i As Integer = 6 To 1 Step -1
            ieee(i) = ieee(i) Or mbf(i) >> 4
            ieee(i - 1) = ieee(i - 1) Or mbf(i) << 4
        Next
        ieee(0) = ieee(0) Or mbf(0) >> 4
    End If

    Return BitConverter.ToDouble(ieee, 0)
End Function


At this Wiki page there's links to a few different code samples for doing this in C, C++ and Python.

One or more of those should hopefully be relatively easy to convert to some language that suits you.


Microsoft has published a KB article about this, including a P/Invokable DLL which you can use to make the conversion from MBF to IEEE.

An archived copy of it is available here.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜