将MBF Double转换为IEEE

时间:2010-09-22 03:00:22

标签: bit-manipulation ieee-754 mbf

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

Convert MBF Single and Double to IEEE

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

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

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

  3. ieee(7)= ieee(7)或签署'为什么不将标志保存到ieee(7)?

  4. ieee(7)= ieee(7)或ToByte(exp>>&4;& HFF)'改变4的原因是什么?

    < / LI>
    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
    

1 个答案:

答案 0 :(得分: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()是相同的。

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

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

Microsoft双二进制格式为:

   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)
  'And&amp; H80'的原因是什么?

十六进制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中的指数是偏向指数。换句话说,存储的值可能是0255,但由这些值表示的实际值可能是-128127(暂时不考虑特殊值)。< / p>

这允许您为非常小的值指定负指数,为大值指定正指数。

MBF指数也存在偏差,但对于单一和双重类型,它们对128有偏见,而IEEE754双精度指数在1023处有0点。

额外-1的原因是因为MBF和IEEE754之间存在隐式1所在位置的差异。 IEEE754将其置于二进制点之前,MBF之后。这意味着指数必须调整一个。

  

ieee(7) = ieee(7) Or sign
  为什么我们不将标志保存到ieee(7)?

这是一个轻微的谜,因为此时ieee(7)尚未明确设定。我只能假设ieee()在创建时已被初始化为零,否则您可能会遇到麻烦,因为这里的每次传输操作都是使用OR完成的。

你是对的,只使用ieee(7) = sign更有意义。组合指数位的实际OR在下一行。

  

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)