Fortran - Precisione numerica
Abbiamo già discusso che, nelle versioni precedenti di Fortran, ce n'erano due real tipi: il tipo reale predefinito e double precision genere.
Tuttavia, Fortran 90/95 fornisce un maggiore controllo sulla precisione dei tipi di dati reali e interi tramite kind specifie.
L'attributo gentile
Diversi tipi di numeri vengono memorizzati in modo diverso all'interno del computer. Ilkindl'attributo consente di specificare come un numero viene memorizzato internamente. Per esempio,
real, kind = 2 :: a, b, c
real, kind = 4 :: e, f, g
integer, kind = 2 :: i, j, k
integer, kind = 3 :: l, m, n
Nella dichiarazione di cui sopra, le variabili reali e, f e g hanno più precisione delle variabili reali a, be c. Le variabili intere l, m e n, possono memorizzare valori più grandi e avere più cifre per la memorizzazione rispetto alle variabili intere i, j e k. Anche se questo dipende dalla macchina.
Esempio
program kindSpecifier
implicit none
real(kind = 4) :: a, b, c
real(kind = 8) :: e, f, g
integer(kind = 2) :: i, j, k
integer(kind = 4) :: l, m, n
integer :: kind_a, kind_i, kind_e, kind_l
kind_a = kind(a)
kind_i = kind(i)
kind_e = kind(e)
kind_l = kind(l)
print *,'default kind for real is', kind_a
print *,'default kind for int is', kind_i
print *,'extended kind for real is', kind_e
print *,'default kind for int is', kind_l
end program kindSpecifier
Quando compili ed esegui il programma sopra, produce il seguente risultato:
default kind for real is 4
default kind for int is 2
extended kind for real is 8
default kind for int is 4
Indagine sulla dimensione delle variabili
Esistono numerose funzioni intrinseche che consentono di interrogare la dimensione dei numeri.
Ad esempio, il file bit_size(i)la funzione intrinseca specifica il numero di bit utilizzati per la memorizzazione. Per numeri reali, ilprecision(x) funzione intrinseca, restituisce il numero di cifre decimali di precisione, mentre il range(x) la funzione intrinseca restituisce l'intervallo decimale dell'esponente.
Esempio
program getSize
implicit none
real (kind = 4) :: a
real (kind = 8) :: b
integer (kind = 2) :: i
integer (kind = 4) :: j
print *,'precision of real(4) =', precision(a)
print *,'precision of real(8) =', precision(b)
print *,'range of real(4) =', range(a)
print *,'range of real(8) =', range(b)
print *,'maximum exponent of real(4) =' , maxexponent(a)
print *,'maximum exponent of real(8) =' , maxexponent(b)
print *,'minimum exponent of real(4) =' , minexponent(a)
print *,'minimum exponent of real(8) =' , minexponent(b)
print *,'bits in integer(2) =' , bit_size(i)
print *,'bits in integer(4) =' , bit_size(j)
end program getSize
Quando compili ed esegui il programma sopra, produce il seguente risultato:
precision of real(4) = 6
precision of real(8) = 15
range of real(4) = 37
range of real(8) = 307
maximum exponent of real(4) = 128
maximum exponent of real(8) = 1024
minimum exponent of real(4) = -125
minimum exponent of real(8) = -1021
bits in integer(2) = 16
bits in integer(4) = 32
Ottenere il valore gentile
Fortran fornisce altre due funzioni intrinseche per ottenere il valore del tipo per la precisione richiesta di numeri interi e reali -
- selected_int_kind (r)
- selected_real_kind ([p, r])
La funzione selected_real_kind restituisce un numero intero che è il valore del parametro di tipo kind necessario per una data precisione decimale pe intervallo di esponente decimale r. La precisione decimale è il numero di cifre significative e l'intervallo di esponenti decimali specifica il numero rappresentabile più piccolo e più grande. L'intervallo è quindi da 10-r a 10 + r.
Ad esempio, selected_real_kind (p = 10, r = 99) restituisce il valore del tipo necessario per una precisione di 10 cifre decimali e un intervallo da almeno 10-99 a 10 + 99.
Esempio
program getKind
implicit none
integer:: i
i = selected_real_kind (p = 10, r = 99)
print *,'selected_real_kind (p = 10, r = 99)', i
end program getKind
Quando compili ed esegui il programma sopra, produce il seguente risultato:
selected_real_kind (p = 10, r = 99) 8