Fortran per Ingegneri Lezione 8 A.A. 2013/2014 Ing. Davide Vanzo [email protected] Ing. Simone Zen [email protected] ufficio: Laboratorio didattico di modellistica ambientale (2° piano) Tel interno: 2488 Additional intrinsic data types Il tipo di dato REAL (floating-point), è usato per rappresentare numeri contenenti decimali. Su molti computer, una variabile real di default è lunga 4 byte (32 bit). E' divisa in due parti, una mantissa e un esponente. Solitamente 24 bit del numero sono utilizzati per rappresentare la mantissa e sono sufficienti per rappresentare 6 o 7 decimali, mentre 8 bit sono utilizzati per l'esponente, e sono sufficienti per rappresentare numeri compresi tra 10**(38) e 10**(-38). 2 Additional intrinsic data types Può accadere che un numero a 32 bit non sia sufficiente a descrivere un valore di cui noi abbiamo bisogno. La versione 'lunga' dei dati tipo REAL è usualmente 8 byte (64bit). 53 bit sono utilizzati per la mantissa (15 o 16 decimali significativi) e 11 bit sono dedicati all'esponente (10**(308), 10**(-308)) 3 Additional intrinsic data types Lo standard del Fortran 90/95 garantisce che un compilatore Fortran supporti almeno queste due dimensioni delle variabili tipo REAL. Comunque nessuno dei produttori specifica quanti bit devono essere utilizzati per ognuna delle dimensioni. Per ragioni storiche la versione più corta dei dati tipo real è chiamata single precision mentre la versione lunga è chiamata double precision 4 Kinds of REAL Constants and Variables REAL(KIND=1) :: valore_1 REAL(KIND=4) :: valore_2 REAL(KIND=8), DIMENSION(20) :: array REAL(4) :: temp Il kind di default può variare tra diversi compilatori e processori, ma solitamente è lungo 32 bit (6 o 7 cifre decimali). Ma cosa significano i numeri di kind (es: kind=1, kind=4, kind=8)? Sfortunatamente ogni venditore di compilatori può assegnare ai vari kind, il valore che più gli aggrada. 5 Kinds of REAL Constants and Variables Per poter rendere portabile un programma, cioè che possa essere utilizzato su diversi computer con diversi compilatori, mantenedo sempre le stesse caratteristiche, si devono assegnare i numeri di kind a costanti che poi vengono utilizzati in fase di dichiarazione: INTEGER, PARAMETER :: SINGLE = 4 !valore dipendente dal compilatore INTEGER, PARAMETER :: DOUBLE = 8 !valore dipendente dal compilatore REAL(KIND=DOUBLE) :: value_1 REAL(KIND=DOUBLE), DIMENSION(20) :: array REAL(SINGLE) :: temp 6 Kinds of REAL Constants and Variables Per conoscere il valore di kind della singola e doppia precisione reale su un particolare computer si può usare il programma seguente: PROGRAM L_8_C1 ! ! Questo codice valuta il kind di singola e doppia precisione ! di un numero reale su un particolare computer ! ! ! dichiarazione delle variabili IMPLICIT NONE ! nessuna dichiarazione implicita INTEGER:: kind_number WRITE(*,'("il KIND per la singola precisione vale",I2)') KIND(0.0) WRITE(*,'("il KIND per la doppia precisione vale",I2)') KIND(0.0D0) STOP END PROGRAM L_8_C1 7 Selezionare la precisione in modo indipendente dal processore INTEGER,PARAMETER:: rk =SELECTED_REAL_KIND(p=precision,r=range) p = precision = è il numero di cifre decimali richieste r = range = è l'esponente richiesto in potenze di 10 8 Selezionare la precisione in modo indipendente dal compilatore rk = SELECTED_REAL_KIND(p=6) > kind = 4 rk = SELECTED_REAL_KIND(p=7) > kind = 8 rk = SELECTED_REAL_KIND(p=9) > kind = 8 rk = SELECTED_REAL_KIND(p=15) > kind = 8 rk = SELECTED_REAL_KIND(p=16) > kind = 16 rk = SELECTED_REAL_KIND(p=33) > kind = 16 rk = SELECTED_REAL_KIND(p=34) > kind = 1 rk = SELECTED_REAL_KIND(r=37) > kind = 4 rk = SELECTED_REAL_KIND(r=307) > kind = 8 rk = SELECTED_REAL_KIND(r=3008) > kind = 16 rk = SELECTED_REAL_KIND(r=4930) > kind = 16 rk = SELECTED_REAL_KIND(r=4940) > kind = 2 Questi parametri sono stati ottenuti con compilatore Intel 9 Perchè non si può sempre usare l'alta precisione? i) I numeri a 64 bit richiedono il doppio della memoria richiesta da quelli a 32 bit; ii) Le operazioni fatte ad alta precisione sono più lente di quelle fatte con una più bassa, il codice sarà più lento (ordine del 30% o più). 10 Quando usare l'alta precisione? 1) Quando devono essere utilizzati numeri il cui valore assoluto è più grande di 10**39 o più piccolo di 10**(-39); 2) Quando nel problema in esame, numeri molto piccoli devono essere sottratti o sommati a numeri molto grandi; 3) Quando il problema richiede che due numeri molto simili debbano essere sottratti o addizionati. 11 Esercizio 1) Calcolare la derivata di in x = 0.15, e con passo spaziale decrescente 2) Valutare l'errore di approssimazione (%) 3) Trasformare il codice in singola precisione appena scritto per poterlo eseguire in doppia precisione. 4) Confrontare i risultati (grafico su excel) 12 Operazioni da svolgere per trasformare un codice da singola precisione a doppia precisione 1) assegnare un parametro in cui si individua il kind da usare: INTEGER,PARAMETER:: rk =SELECTED_REAL_KIND(p=precision,r=range) vi basta assegnare p=6 per singola, p=15 per doppia 2) dichiarare tutte le variabili in precisione rk REAL(kind=rk):: variabile1, variabile2 3) Trasformare tutti i numeri reali che appaiono nel codice in precisione rk Valore1 = 1.0/3.0*valore2*10.0**2 ===> Valore1 = 1.0_rk/3.0_rk*valore2*10.0_rk**2 13 14
© Copyright 2024 ExpyDoc