Будет ли этот С++ конвертировать 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.