lezione 8

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