IEEE Doppia precisione in Blitz2
Per usare il mio codice non dovete far altro che XINCLUDErlo all'inizio del vostro programma, ed assicurarvi di avere le due librerie "mathieeedoubbas.library" e "mathieeedoubtrans.library" sul vostro disco di sistema.
Il nome del tipo in doppia precisione è "longreal": esso è costituito da due longword. Potete usarlo solo per mezzo dei puntatori: vale a dire, per creare una variabile longreal dovete definirla (DEFTYPE) come un puntatore a longreal e poi inizializzarla utilizzando la funzione dNew{}. Ecco un esempio:
DEFTYPE.longreal *pippo *pippo=dNew{}
e poi potete usare *pippo con le routine a doppia precisione (attenzione a non dimenticare l'asterisco (*)!). Se dimenticate di inizializzare una variabile prima di usarla, la vostra macchina gurerà. Ovviamente potete maneggiare una variabile longreal solo per mezzo delle routine a doppia precisione poiché il tipo longreal non è un tipo primitivo di Blitz2 (è una specie di trucco). Prima di uscire dal programma dovete liberare tutte le variabili longreal che avete precedentemente inizializzato: per far ciò scrivete semplicemente
dFree{*pippo}Se dimenticate di liberare una variabile, la memoria allocata per essa verrà persa.
Ora descriverò le routine di conversione. Per inserire un numero a doppia precisione dovete scriverlo in una stringa e poi convertirlo in un longreal utilizzando la funzione a2d{}:
a2d{stringa$, *longreal}
La variabile *longreal conterrà il vostro numero. La funzione a2d{} accetta anche la notazione scientifica: 12e3 o 12E3. Per riconvertire il numero in stringa vi sono due funzioni: dFormat{} e dLFormat{}. La prima è utilizzata per numeri piccoli e non negativi, mentre la seconda accetta ogni tipo di numero (e permette anche l'output in notazione scientifica). La sintassi è:
stringa$=dFormat{*longreal, cifre} stringa$=dLFormat{*longreal, cifre, potenza_max}dove: *longreal è il numero da convertire; cifre è il numero di caratteri ascii utilizzati per rappresentare il numero convertito; potenza_max è una specie di soglia: se il numero è maggiore di 10^potenza_max allora la routine userà la notazione scientifica.
Le altre routine costituiscono tutte le operazioni che potete effettuare sul tipo a doppia precisione: in generale, esse accettano uno o due longreal come argomenti e pongono il risultato dell'operazione nel primo argomento, quindi ricordatevi di copiarlo se non volete perderlo. Per copiare un longreal usate
dCopy{*longreal1, *longreal2}
dove, come dice la regola generale, la variabile destinazione è la prima. Routine insolite, per quanto riguarda la loro sintassi, sono
long=dFix{*longreal}
converte un longreal in intero;
dFloat{long, *longreal}
converte un intero in longreal;
risultato=dTst{*longreal}
confronta *longreal con il valore 0.0: resituisce -1 se *longreal<0, 0 se *longreal=0 e 1 se *longreal>0;
risultato=dCompare{*longreal1, *longreal2}
confronta i due longreal e restituisce: -1 se *longreal1<*longreal2, 0 se *longreal1=*longreal2 e 1 se *longreal1>*longreal2;
dDouble{IeeeSingle, *longreal}
converte un valore Ieee singola precisione in un valore a doppia precisione;
IeeeSingle=dSingle{*longreal}
converte un valore a doppia precisione in un valore a singola precisione;
dPi{*longreal}
mette il valore di Pi (3.141592...) in *longreal. Esempi di operazioni standard sono
dAdd{*longreal1, *longreal2}
somma i due numeri e restituisce il risultato in *longreal1;
dRad{*longreal}
converte i gradi in radianti per essere usati con le funzioni angolari;
dSqrt{*longreal}
calcola la radice quadrata di *longreal e la pone in *longreal. A proposito: non vi è controllo per errori come passare un argomento negativo a dSqrt{}, dovete farlo voi; e se passate un valore negativo a dSqrt{} la vostra macchina si pianterà senza nemmeno avvisarvi.
Non riporterò tutte le funzioni numeriche implementate: il sorgente è ampiamente commentato e quindi vi invito a dargli un'occhiata.
Per essere sincero devo dire che se convertite, per esempio, il numero "1.23" (con a2d{"1.23",*longreal}) e poi lo riconvertite in stringa (con s$=dFormat{*longreal,10}) vi ritroverete con "1.229999999": probabilmente le routine di conversione possono essere migliorate, ma finora non so se questo è completamente dovuto a me; probabilmente questo è dovuto anche agli errori di arrotondamento del formato Ieee od alla funzione IeeeDPFloor (e/o IeeeDPCeil), inclusa nelle librerie Ieee, che uso durante la conversione.
Per il sorgente in LHA, premere qui.
Scritto da: Andrea Galimberti e-mail: fsoft@intercom.it Via E.Villoresi Turbigo (MI) ITALY tel: (ITA) - (0)331 - 871009