2010-02-12 16 views
10

Sto mantenendo un programma che prende i dati da un programma PDP-11 (emulato!) E lo inserisce in un moderno sistema basato su Windows. Stiamo riscontrando problemi con alcuni dei valori dei dati riportati come "1. # QNAN" e anche "1. # QNB". Il cliente ha recentemente rivelato che i valori "cattivi" nel programma PDP-11 sono rappresentati da 2 parole a 16 bit con tutti i bit impostati tranne il primo. Penso che sia quando proviamo a convertirli in float IEEE che stiamo ricevendo gli errori.Questo C++ convertirà PDP-11 in IEEE?

Ho trovato il codice seguente che viene utilizzato per convertire i valori PDP-11 in IEEE. Non sono molto in contatto con la complessità delle rappresentazioni in virgola mobile ma questo mi sembra un po 'semplice! Sarebbe davvero in grado di convertire in modo affidabile i float PDP-11 in 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.

+3

+1 semplicemente per il fatto che si deve mantenere il codice PDP-11. –

+0

Si noti che '1. # QNB' è semplicemente' 1. # QNAN' "arrotondato" a 4 posizioni. (Non riesco a trovare la domanda SO precedente sul caso più comune di "# INF" che è "arrotondato" a "# J".) –

risposta

0

Il PDP-11 utilizzava una rappresentazione mixed-endian per i numeri in virgola mobile. quindi questa parte del codice

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

è corretto se i dati non sono già stati scambiati con parole prima di averlo ottenuto.

Questo documento fornisce i dettagli della rappresentazione per un sacco di diversi formati decimali http://www.quadibloc.com/comp/cp0201.htm

Dice che t PDP-11/VAX usato in eccesso 128 notazione per l'esponente. mentre IEEE 754 utilizza la notazione in eccesso di 126, quindi se è corretta, la divisione per 4 sembra essere il modo corretto per regolare l'esponente.

Tuttavia, Wikipedia afferma che il bias esponenziale per IEEE 754 è 127, non 126. Pertanto, il documento sopra riportato utilizza una notazione strana o non è corretto. È possibile che sia necessario dividere per 2 piuttosto che per 4.

1

Da this page, il formato PDP-11 è identico al formato a virgola mobile IEEE-754 tranne che l'esponente è polarizzato di 128 in PDP-11, mentre è polarizzato da 127 in IEEE-754. Quindi, è necessario dividere per 2.0 e non per 4.0. Questo non si prende cura dei NaN e degli infiniti, ma dalle mie ricerche su google sembra che PDP-11 non li abbia.

Problemi di overflow. Il formato PDP sfiora in precedenza, ma suppongo che sia OK, dal momento che non si può fare nulla una volta che un numero è già stato sorpassato.

+0

errato. Dovrebbe essere diviso per 4. Vedi la mia risposta qui sotto. – marcin

0

Oltre a NaN e Inf, è possibile che si verifichino problemi con la conversione dei valori di denormal. Non so se il PDP-11 supporti questi, ma IEEE 754 afferma che quando il campo esponente è 0, i numeri sono denormali, il che significa che l'iniziale implicita 1 nel campo della mantissa diventa uno 0. In questo modo c'è un convergenza graduale a 0 quando i numeri diminuiscono.

@John - Lo standard IEEE 754 afferma che il bias dell'esponente è 127, non 126. Wiki ha ragione e l'altro riferimento è sbagliato. Quindi, il rapporto sarebbe 2.0.

2

Il codice non verifica valore indefinito, pulito zero e sporco zero, ma dividendo per 4, discusso in altre risposte, è buono. Probabilmente l'OP lo sa perché individuerebbe se il risultato fosse sempre sbagliato. Il bias esponente anche mi ha confuso oggi, quindi mi cito quello che ho appena letto in questo bel documento: Binary floats with hidden bit:

In un primo momento il bit nascosta è dato un'altra posizione. IEEE assume questo bit prima del periodo frazionario e Digital lo assume immediatamente dopo lo in quel periodo. Secondo IEEE, la parte visibile della mantissa ('visman') inizia immediatamente dopo il periodo, mentre secondo Digital inizia dietro il bit nascosto. Così il campo di valori della mantissa totale è:

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

Al secondo gli extra-bias nella notazione dell'esponente differiscono. [Da 1 ...]

Entrambi gli effetti insieme fanno si che la sequenza di bit in un galleggiante IEEE- rappresenta un numero quattro volte nella dimensione del valore lo stesso bit modello in un Digital galleggiante significa.

spiega anche il motivo per cui alcuni riferimenti affermano che pregiudizi IEEE è 126.