1

我在下面找到了一个将 MBF 转换为 IEEE 的主题。

将 MBF Single 和 Double 转换为 IEEE

任何人都可以解释下面标记的代码的功能是什么?

  1. Dim sign As Byte = mbf(6) And ToByte(&H80) 'AND (&H80) 的原因是什么?

  2. Dim exp As Int16 = mbf(7) - 128S - 1S + 1023S '为什么是 1152 (128+1+1023)?

  3. ieee(7) = ieee(7) 或 sign '为什么不直接将符号保存到 ieee(7)?

  4. ieee(7) = ieee(7) 或 ToByte(exp >> 4 And &HFF) '什么是移位 4 的原因?


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
4

1 回答 1

6

IEEE754 双精度格式由 1 位符号、11 位指数和 52 位尾数组成:

   7        6        5        4        3        2        1        0
seeeeeee eeeemmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm 

由于字节顺序的变幻莫测,左边的最高有效字节实际上是ieee(7),右边的最低有效字节是ieee(0)- 这与mbf()下面的相同。

指数为您提供一个0通过2047(2 11 -1) 的值,其中一些用于表示特殊值,例如+/-inf(无穷大)和nan(不是数字)。

尾数位从左到右表示 , 1/2,1/4等等1/8。为了得到这个数字,你计算 n = (-1) s x 2 e-bias x 1.m

微软双二进制格式为:

   7        6        5        4        3        2        1        0
eeeeeeee smmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm

您看到的代码只是将值从 MBF 传输(并略微更改)为 IEEE754 双精度格式。

要回答您的具体问题:

Dim sign As Byte = mbf(6) And ToByte(&H80)
'和&H80'的原因是什么?

Hex 80( &H80) 是二进制模式1000 0000

当您AND使用该值时,您会得到&H80该位是否已设置0

这基本上只是记录数字的符号是什么,您可以简单地将其从 转移mbf(6)ieee(7)

Dim exp As Int16 = mbf(7) - 128S - 1S + 1023S
为什么是 1152 (128+1+1023)?

IEEE754 中的指数是有指数。换句话说,存储的值可能是0thru 255,但它们表示的实际值可能是-128thru 127(暂时忽略特殊值)。

这允许您对非常小的值使用负指数,对大值使用正指数。

MBF 指数也有偏差,但它们对128单精度和双精度类型都有偏差,而 IEEE754 双精度指数的 0 点位于1023.

额外的原因-1是因为 MBF 和 IEEE754 之间关于隐式去向的差异1。IEEE754 将它放在二进制点之前,MBF 之后。这意味着指数必须调整一。

ieee(7) = ieee(7) Or sign
为什么我们不直接将符号保存到 ieee(7)?

这有点神秘,因为那时ieee(7)还没有明确设置。我只能假设ieee()在创建时已将其初始化为零,否则您可能会遇到麻烦,因为这里几乎每个传输操作都是使用OR.

你是对的,只使用ieee(7) = sign. 组合指数位的实际ORing 在下一行。

ieee(7) = ieee(7) Or ToByte(exp >> 4 And &HFF)
移动4的原因是什么?

因为 IEEE754 指数跨越两个字节,而您只希望该指数的一部分在最重要的一个字节中。指数的七位进入最高有效字节,其他四位进入下一个字节。

这由两行处理:

ieee(7) = ieee(7) Or ToByte(exp >> 4 And &HFF) ' upper 7 bits '
ieee(6) = ieee(6) Or ToByte(exp << 4 And &HFF) ' lower 4 bits '

给定 16 位值00000abcdefghijk,计算两者:

>> 4 and &hff : 0abcdefg (s will go at the left)
<< 4 and &hff : hijk0000 (m will go at the right)
于 2010-09-22T03:25:20.670 回答