我在下面找到了将MBF转换为IEEE的主题。
Convert MBF Single and Double to IEEE
任何人都可以解释下面标记的代码的功能是什么?
Dim sign As Byte = mbf(6)和ToByte(& H80)'是什么原因AND(& H80)?
Dim exp As Int16 = mbf(7) - 128S - 1S + 1023S '为什么是1152(128 + 1 + 1023)?
ieee(7)= ieee(7)或签署'为什么不将标志保存到ieee(7)?
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
答案 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()
是相同的。
指数为您提供0
到2047
的值(2 11 -1),其中一些用于表示+/-inf
等特殊值(无穷大)和nan
(不是数字)。
尾数位从左到右表示1/2
,1/4
,1/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中的指数是偏向指数。换句话说,存储的值可能是0
到255
,但由这些值表示的实际值可能是-128
到127
(暂时不考虑特殊值)。< / 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)