我正在维护一个程序,该程序从PDP-11(模拟!)程序中获取数据并将其放入基于Windows的现代系统中。我们遇到的问题是某些数据值被报告为“1.#QNAN”以及“1.#QNB”。客户最近透露,PDP-11程序中的“坏”值由2个16位字表示,除第一个之外设置了所有位。我认为,当我们尝试将这些转换为IEEE浮点数时,我们会收到错误。
我发现下面的代码用于将PDP-11值转换为IEEE。我对浮点表示的复杂性并不是很了解,但这对我来说似乎有点简单!这是否真的可靠地将PDP-11浮标转换为IEEE?
// ---------------------------------------------------------------- cnvPDPfloat
// CNVPDPFLOAT
// ----------------------------------------------------------------------------
//
// Converts PDP11 float (two 16-bit words) into IEEE float
//
// PDP11 and IEEE floats have same layout so can be mapped onto eachother.
// But PDP11 exponent must have 2 subtracted for IEEE. Or just divide by 4.
//
float cnvPDPfloat( PDP11Float input )
{
union
{
unsigned long pdp11;
float ieee;
} uFloat;
uFloat.pdp11 = (input.word[0] << 16) + input.word[1];
return (uFloat.ieee / (float) 4.0);
}
--- Alistair。
答案 0 :(得分:2)
代码不检查未定义值, clean-zero 和 dirty-zero ,但除以4,在其他讨论答案,很好。 OP可能知道它,因为他们会发现结果总是错误的。 指数偏见今天也让我感到困惑,所以我将引用我在这篇优秀文件中所读到的内容:Binary floats with hidden bit:
首先,隐藏位被赋予另一个位置。 IEEE假设这一点 在分数周期之前和Digital紧接着它之后 那个时期。根据IEEE尾数的可见部分 ('visman')在这段时间后立即开始,而根据 数字它从隐藏位开始。因此价值范围 总尾数是:
IEEE: 1.0 =< (1.visman) < 2.0 Digital: 0.5 =< (0.1 visman) < 1.0
第二,指数表示法中的过量偏差不同。 [由1 ...]
这两种效果共同构成IEEE-float中的位模式 表示相同位的值的大小的四倍 Digital-float中的模式代表。
这也解释了为什么有些参考文献声称IEEE偏差是126。
答案 1 :(得分:1)
从this page开始,PDP-11格式与IEEE-754浮点格式相同,只是指数在PDP-11中偏向128,而在IEEE-754中则偏向127。所以,你需要除以2.0而不是4.0。这不会照顾NaN和无穷大,但是从我的谷歌搜索来看,看起来PDP-11没有那些。
您还会遇到溢出问题。 PDP格式早先溢出,但我认为没关系,因为一旦数字已经溢出,你就无法做任何事情。
答案 2 :(得分:0)
PDP-11使用混合端表示来表示浮点数。所以这部分代码
uFloat.pdp11 = (input.word[0] << 16) + input.word[1];
如果您的数据在获得之前尚未进行过单词交换,则是正确的。
本文档详细介绍了许多不同浮点格式http://www.quadibloc.com/comp/cp0201.htm
的表示形式它说t PDP-11 / VAX对指数使用了超过128的表示法。而IEEE 754使用了超过126的表示法,所以如果它是正确的,除以4似乎是调整指数的正确方法。
然而,维基百科说IEEE 754的指数偏差是127,而不是126.所以上述文件使用的是奇怪的符号,或者它是不正确的。您可能需要除以2而不是4。
答案 3 :(得分:0)
除了NaN和Inf之外,您还可能在转换非正常值时遇到问题。我不知道PDP-11是否支持这些,但IEEE 754规定,当指数字段为0时,则数字为非正规数,实际上意味着尾数字段中隐含的前导1变为0。这样就有了当数字减少时,逐渐收敛到0。
@John - IEEE 754标准规定指数偏差为127,而不是126.Wiki是正确的,另一个参考是错误的。所以,这个比例是2.0。