Будет ли этот C ++ преобразовывать PDP-11 с плавающей точкой в ​​IEEE? - PullRequest
10 голосов
/ 12 февраля 2010

Я поддерживаю программу, которая берет данные из программы PDP-11 (эмулированной!) И помещает их в современную систему на базе Windows. У нас возникли проблемы с некоторыми значениями данных, сообщаемыми как «1. # QNAN», а также «1. # QNB». Недавно заказчик обнаружил, что «плохие» значения в программе PDP-11 представлены 2 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);
}

--- Алистер.

Ответы [ 4 ]

2 голосов
/ 16 сентября 2012

Код не проверяет неопределенное значение , чистый-ноль и грязный-ноль , но деление на 4, обсуждаемое в других ответах, является хорошо. ФП, вероятно, знает это, потому что они заметили бы, если результат всегда был неправильным. Смещение экспоненты также смутило меня сегодня, поэтому я процитирую то, что я только что прочитал в этом прекрасном документе: Двоичные числа с скрытым битом :

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

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

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

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

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

1 голос
/ 12 февраля 2010

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

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

0 голосов
/ 16 февраля 2010

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

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

0 голосов
/ 12 февраля 2010

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

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

...