我在python中解析十六进制格式的DEC 32位单精度浮点值时遇到问题,我正在解析的值以十六进制表示为D44393DB。原始浮点值为~108,从发送单元的显示中读取。
格式指定为: 1位符号+ 8位指数+ 23位尾数。 字节2包含符号位+指数的7个最高有效位 字节1包含指数的最低有效位+尾数的起始最高有效位。
我发现两种格式中唯一不同的是指数偏差,DEC32为128,IEEE-754为127(http://www.irig106.org/docs/106-07/appendixO.pdf)
使用http://babbage.cs.qc.edu/IEEE-754/32bit.html无法获得预期结果。
/的Kristofer
答案 0 :(得分:3)
字节是否有可能以某种方式被洗牌?您描述的位排列(字节2中的符号位,字节1中指数的LSB)与您链接到的附录O不同。它看起来像是字节1和2被交换了。
我假设还交换了字节3和4,因此实际的十六进制值是43D4DB93。这转换为二进制的0100 0011 1101 0100 1101 1011 1001 0011,因此符号位为0,表示正数。指数为10000111(二进制)= 135(十进制),表示系数为2 ^(135-128)= 128.最后,尾数为0.1101 0100 1101 1011 1001 0011(二进制),使用附录O表示你有在前面加0.1,小数约为0.8314。所以根据我的假设你的数字是0.8314 * 128 = 106.4。
已添加:某些Python 2代码可能会澄清:
input = 0xD44393DB;
reshuffled = ((input & 0xFF00FF00) >> 8) | ((input & 0x00FF00FF) << 8);
signbit = (reshuffled & 0x80000000) >> 31;
exponent = ((reshuffled & 0x7F800000) >> 23) - 128;
mantissa = float((reshuffled & 0x007FFFFF) | 0x00800000) / 2**24;
result = (-1)**signbit * mantissa * 2**exponent;
这会产生result = 106.42885589599609
。
这是对计算尾数的线的解释。首先,reshuffled & 0x007FFFFF
产生编码尾数的23位:101 0100 1101 1011 1001 0011.然后... | 0x00800000
设置隐藏位,产生1101 0100 1101 1011 1001 0011.我们现在必须计算分数0.1101 0100 1101 1011 1001 0011.根据定义,这等于1*2^(-1) + 1*2^(-2) + 0*2^(-3) + ... + 1*2^(-23) + 1*2^(-24)
。这也可以写成(1*2^23 + 1*2^22 + 0*2^21 + ... + 1*2^1 + 1*2^0) / 2^24
。括号中的表达式是1101 0100 1101 1011 1001 0011(二进制)的值,因此我们可以通过将(reshuffled & 0x007FFFFF) | 0x00800000
除以2 ^ 24来找到尾数。
答案 1 :(得分:1)
从我的“微型计算机和记忆”(DEC,1981)的副本中,你对两种格式之间的区别是正确的。 DEC尾数标准化为0.5<=f<1
,IEEE格式尾数标准化为1<=f<2
,MSB隐式且未存储。因此,尾数位布局是相同的。由于D44393DB的值为-0.7639748 X 2 ^ 40(即-8.3999923E11),因此Jitse Niesens的假设看起来似乎是合理的解释。
答案 2 :(得分:1)
在RHS的“相关”下找到:these answers from last month
其中一个引用有助于理解“有线”(奇怪的?)byte2 byte1表示法。
答案 3 :(得分:0)
它绝对是DEC32值吗?符号位似乎为1,表示此格式为负。但是,如果忽略这一点,你会得到一个非常接近108值的结果,并假设指数偏差为15,在尾数上保留0.1因子:
def decode(x):
exp = (x>>30) & 0xff
mantissa = x&((2**24)-1)
return 0.1 * mantissa * (2**(exp-15))
>>> decode(0xD44393DB)
108.12409668