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