English 中文(简体)
这个 C++ 程序能把 PDP-11 的浮点数转换成 IEEE 标准吗?
原标题:Will this C++ convert PDP-11 floats to IEEE?

我正在维护一个程序,该程序从PDP-11(模拟!)程序中获取数据,并将其放入现代的基于Windows的系统中。我们遇到了一些数据值报告为“1.#QNAN”和“1.#QNB”的问题。客户最近透露,在PDP-11程序中,坏数据值由两个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);
}

艾利斯特。

问题回答

The code doesn t check for undefined value, clean-zero and dirty-zero, but dividing by 4, discussed in other answers, is good. The OP probably knows it because they would spot if the result was always wrong. The exponent bias also confused me today, so I ll quote what I ve just read in this fine document: Binary floats with hidden bit:

At first the hidden bit is given another position. IEEE assumes this bit before the fractional period and Digital assumes it immediately after that period. According to IEEE the visible part of the mantissa ( visman ) starts immediately after the period, whilst according to Digital it starts behind the hidden bit. Thus the value range of the total mantissa is:

IEEE:      1.0 =<  (1.visman)  < 2.0
Digital:   0.5 =< (0.1 visman) < 1.0

第二,在标注时的过分偏差各不相同。 [......]

Both effects together make that the bit pattern in an IEEE- float represents a number four times in size of the value the same bit pattern in a Digital-float stands for.

这也解释了为什么一些参考文献指出IEEE偏差为126。

这个页面可知,PDP-11格式与IEEE-754浮点数格式相同,但是PDP-11中的指数偏移量为128,而在IEEE-754中为127。因此,您需要除以2.0而不是4.0。这不包括NaN和无限大,但从我的谷歌搜索中看来,PDP-11没有这些。

你还会遇到溢出的问题。PDP格式的溢出会更早,但我假设这没关系,因为一旦一个数字已经溢出了,你实际上无法做任何事情。

PDP-11使用混合字节序表示浮点数。因此,代码的这一部分

uFloat.pdp11 = (input.word[0] << 16) + input.word[1];

如果在获取数据之前,您的数据还没有被单词交换过,则是正确的。

本文详细介绍了许多不同浮点格式的表示方式。 http://www.quadibloc.com/comp/cp0201.htm

它说PDP-11 / VAX使用超过128的符号表示指数,而IEEE 754使用超过126的符号表示,因此如果正确的话,除以4似乎是调整指数的正确方式。

然而,维基百科称IEEE 754的指数偏差为127,而不是126。因此,以上文件使用了奇怪的符号,或者是不正确的。你可能需要除以2而不是4。

除了NaN和Inf之外,您可能还会遇到转换微小值的问题。我不知道PDP-11是否支持这些功能,但IEEE 754规定,当指数字段为0时,数字为微小值,这实际上意味着尾数字段中隐含的前导1变为0。这样,当数字减少时,就会逐渐收敛于0。

约翰-IEEE 754标准规定指数偏差为127,而不是126。维基是正确的,其他参考是错误的。因此,比率为2.0。





相关问题
Haskell minimum/maximum Double Constant

Is there any way in Haskell to get the constant that is the largest and smallest possible positive rational number greater than zero that can be represented by doubles?

integer automatically converting to double but not float

I have a function like below: void add(int&,float&,float&); and when I call: add(1,30,30) it does not compile. add(1,30.0,30.0) also does not compile. It seems that in both cases, it ...

Lower Bounds For Floating Points

Are there any lower bounds for floating point types in C? Like there are lower bounds for integral types (int being at least 16 bits)?

Floating point again

Yesterday I asked a floating point question, and I have another one. I am doing some computations where I use the results of the math.h (C language) sine, cosine and tangent functions. One of the ...

热门标签