views:

247

answers:

3

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.

A: 

The PDP-11 used a mixed-endian representation for floating point numbers. so this part of the code

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

is correct if your data hasn't already been word-swapped before you get it.

This document gives details of the representation for a lot of different floating point formats http://www.quadibloc.com/comp/cp0201.htm

It says that t PDP-11/VAX used excess 128 notation for the exponent. whereas IEEE 754 uses excess 126 notation, so if it is correct, dividing by 4 seems to be the correct way to adjust the exponent.

However, Wikipedia says that the exponent bias for IEEE 754 is 127, not 126. So either the above document is using a strange notation, or it is incorrect. It's possible that you need to divide by 2 rather than by 4.

John Knoeller
+1  A: 

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.

Alok
A: 

In addition to NaN and Inf, you may also have problems with conversion of denormal values. I don't know if PDP-11 supports these, but IEEE 754 states that when the exponent field is 0, then the numbers are denormals, effectively meaning that the implied leading 1 in the mantissa field becomes a 0. This way there is a gradual convergence to 0 when numbers are decreasing.

@John - The IEEE 754 standard states that the exponent bias is 127, not 126. Wiki is right and the other reference is wrong. So, the ratio would be 2.0.

ysap