Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Will this C++ convert PDP-11 floats to IEEE?

I am maintaining a program that takes data from a PDP-11 (emulated!) program and puts it into a modern Windows-based system. We are having problems with some of the data values being reported as "1.#QNAN" and also "1.#QNB". The customer has recently revealed that 'bad' values in the PDP-11 program are represented by 2 16-bit words with all the bits set except the first. I think that it is when we try to convert these to IEEE floats that we are getting the errors.

I have found the code below that is used for converting the PDP-11 values to IEEE. I am not very in touch with the intricacies of floating point representations but this seems a bit simple to me! Would this really reliably convert PDP-11 floats to 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.

like image 218
user41013 Avatar asked Feb 12 '10 09:02

user41013


2 Answers

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

At second the excess-biases in the notation of the exponent differ. [by 1 ...]

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.

This also explains why some references state that IEEE bias is 126.

like image 74
marcin Avatar answered Dec 17 '22 21:12

marcin


From this page, the PDP-11 format is identical to IEEE-754 floating-point format except that the exponent is biased by 128 in PDP-11, whereas it is biased by 127 in IEEE-754. So, you need to divide by 2.0 and not 4.0. This doesn't take care of NaNs and infinities, but from my google searches, looks like PDP-11 didn't have those.

You will also have issues with overflow. The PDP format overflows earlier, but I am assuming that is OK since you can't really do anything once a number has already overflown.

like image 29
Alok Singhal Avatar answered Dec 17 '22 20:12

Alok Singhal