Будет ли этот С++ конвертировать PDP-11 в IEEE?

Я поддерживаю программу, которая берет данные из программы PDP-11 (emulated!) и помещает ее в современную систему на базе 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);
}

--- Алистер.

Ответ 1

Код не проверяет значение undefined, clean-zero и dirty-zero, но деление на 4, обсуждаемое в других ответах, является хорошим. ОП, вероятно, это знает, потому что они будут видеть, всегда ли результат был неправильным. Предположение об экспоненциальности также смутило меня сегодня, поэтому я приведу то, что я только что прочитал в этом прекрасном документе: Двоичные поплавки со скрытым битом:

Сначала скрытый бит получает другую позицию. IEEE принимает этот бит до дробного периода, и Digital принимает это сразу после этот период. Согласно IEEE, видимая часть мантиссы ( "visman" ) начинается сразу после периода, тогда как согласно Цифровой он начинается за скрытым битом. Таким образом, диапазон значений общая мантисса:

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

Во-вторых, избыточные смещения в обозначении показателя отличаются. [на 1...]

Оба эффекта вместе делают так, что битовая диаграмма в IEEE-float представляет собой число в четыре раза по величине одного и того же бита шаблон в цифровом поплавке означает.

Это также объясняет, почему в некоторых ссылках указано, что смещение IEEE равно 126.

Ответ 2

Из эта страница формат PDP-11 идентичен формату с плавающей запятой IEEE-754, за исключением того, что экспонента смещена на 128 в PDP-11, тогда как в IEEE-754 он смещен на 127. Итак, вам нужно разделить на 2.0, а не 4.0. Это не заботится о NaN и бесконечностях, но из моих поисковых запросов Google выглядит так, что у PDP-11 этого нет.

У вас также будут проблемы с переполнением. Формат PDP переполняется раньше, но я предполагаю, что это нормально, так как вы не можете ничего сделать, как только число уже переполнено.

Ответ 3

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 кажется правильным способом настройки экспоненты.

Однако, Wikipedia говорит, что смещение экспоненты для IEEE 754 составляет 127, а не 126. Таким образом, либо в вышеупомянутом документе используется странная нотация, либо неверна. Возможно, вам нужно разделить на 2, а не на 4.

Ответ 4

В дополнение к NaN и Inf, у вас также могут быть проблемы с преобразованием денормальных значений. Я не знаю, поддерживает ли PDP-11, но IEEE 754 утверждает, что когда поле экспоненты равно 0, то числа являются денормалами, что фактически означает, что подразумеваемый ведущий 1 в поле мантиссы становится равным 0. Таким образом, существует постепенная сходимость к 0, когда числа уменьшаются.

@John - В стандарте IEEE 754 указано, что смещение экспоненты составляет 127, а не 126. Wiki прав, а другая ссылка неверна. Таким образом, отношение будет равно 2,0.