2010-02-12 7 views
10

Ich führe ein Programm, das Daten von einem PDP-11 (emuliert!) Programm nimmt und es in ein modernes Windows-basiertes System bringt. Wir haben Probleme mit einigen Datenwerten, die als "1. # QNAN" und auch als "1. # QNB" gemeldet werden. Der Kunde hat kürzlich offenbart, dass "schlechte" Werte im PDP-11-Programm durch 2 16-Bit-Wörter mit allen gesetzten Bits außer dem ersten dargestellt werden. Ich glaube, wenn wir versuchen, diese in IEEE-Floats umzuwandeln, bekommen wir die Fehler.Wird dieses C++ PDP-11 zu IEEE?

Ich habe den folgenden Code gefunden, der für die Konvertierung der PDP-11-Werte in IEEE verwendet wird. Ich bin nicht sehr in Kontakt mit den Feinheiten von Gleitkommadarstellungen, aber das scheint mir ein bisschen einfach zu sein! Würde das PDP-11 wirklich zuverlässig in IEEE konvertieren?

// ---------------------------------------------------------------- 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.

+3

+1 einfach für die Tatsache ist, dass Sie pdp-11-Code zu erhalten. –

+0

Beachten Sie, dass '1. # QNB' einfach" 1. # QNAN' "auf" 4 "gerundet ist. (Ich kann die vorherige SO-Frage über den häufigeren Fall von "# INF", der zu "# J" gerundet wird, nicht finden.) –

Antwort

0

Der PDP-11 verwendete eine Mischendian-Darstellung für Gleitkommazahlen. also dieser Teil des Codes

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

ist korrekt, wenn Ihre Daten nicht bereits Word-swapped, bevor Sie es bekommen haben.

Dieses Dokument enthält Einzelheiten der Darstellung für viele verschiedene Gleitkommaformate http://www.quadibloc.com/comp/cp0201.htm

Er sagt, dass t PDP-11/VAX Überschuss 128 Notation für die Exponenten verwendet. während IEEE 754 eine übermäßige 126-Notation verwendet, scheint die Division durch 4 die richtige Art zu sein, den Exponenten anzupassen, wenn es korrekt ist.

Jedoch, Wikipedia sagt, dass der Exponent Bias für IEEE 754 ist 127, nicht 126. So entweder das oben genannte Dokument verwendet eine seltsame Notation, oder es ist falsch. Es ist möglich, dass Sie durch 2 statt durch 4 dividieren müssen.

1

Von this page, das PDP-11-Format ist identisch mit IEEE-754 Fließkomma-Format, außer dass der Exponent in PDP-11 um 128 vorgespannt ist es ist in IEEE-754 durch 127 vorgespannt. Sie müssen also durch 2,0 und nicht durch 4,0 teilen. Dies kümmert sich nicht um NaNs und Unendlichkeiten, aber bei meinen Google-Suchen sieht es so aus, als hätte PDP-11 diese nicht.

Sie werden auch Probleme mit Überlauf haben. Das PDP-Format ist früher übergelaufen, aber ich gehe davon aus, dass das OK ist, da Sie wirklich nichts tun können, sobald eine Zahl bereits übergelaufen ist.

+0

falsch. Es sollte durch 4 geteilt werden. Siehe meine Antwort unten. – marcin

0

Zusätzlich zu NaN und Inf können Sie auch Probleme mit der Konvertierung von Denormalwerten haben. Ich weiß nicht, ob PDP-11 diese unterstützt, aber IEEE 754 besagt, dass, wenn das Exponentenfeld 0 ist, die Zahlen denormal sind, was bedeutet, dass die implizierte führende 1 im Mantissenfeld eine 0 wird. Auf diese Weise gibt es a allmähliche Konvergenz auf 0, wenn die Anzahl abnimmt.

@John - Der IEEE 754-Standard besagt, dass die Exponentenvorgabe 127 ist, nicht 126. Wiki ist richtig und die andere Referenz ist falsch. Also wäre das Verhältnis 2,0.

2

Der Code nicht für undefinierten Wert von 4,, Rein Null und schmutzig-Null, aber Teilung in anderen Antworten diskutierte nicht überprüft, ist gut. Das OP weiß es wahrscheinlich, weil sie sehen würden, ob das Ergebnis immer falsch war. Der Exponent Bias verwirrt mich auch heute, so werde ich zitieren, was ich in diesem feinen Dokument nur lesen: Binary floats with hidden bit:

Zunächst wird die versteckte Bit eine andere Position gegeben ist. IEEE nimmt dieses Bit vor der Nachkomma-Periode an und Digital nimmt es sofort nach dieser Periode an. Nach IEEE beginnt der sichtbare Teil der Mantisse ('visman') unmittelbar nach der Periode, während nach Digital es hinter dem versteckten Bit startet. Somit ist der Wertebereich der Gesamt Mantisse:

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

Auf dem zweiten die über Vorspannungen in der Notation des Exponenten unterscheiden. [durch 1 ...]

Beide Effekte zusammen machen, dass das Bitmuster in einem IEEE-float eine Zahl darstellt, die vier Mal so groß ist wie das Bit Muster in einem Digital-float.

Dies erklärt auch, warum einige Referenzen angeben, dass IEEE Bias 126

Verwandte Themen