Fortran - Precisión numérica

Ya hemos comentado que, en versiones anteriores de Fortran, había dos real tipos: el tipo real predeterminado y double precision tipo.

Sin embargo, Fortran 90/95 proporciona más control sobre la precisión de los tipos de datos reales y enteros a través del kind especifie.

El atributo amable

Los diferentes tipos de números se almacenan de manera diferente dentro de la computadora. loskindEl atributo le permite especificar cómo se almacena un número internamente. Por ejemplo,

real, kind = 2 :: a, b, c
real, kind = 4 :: e, f, g
integer, kind = 2 :: i, j, k
integer, kind = 3 :: l, m, n

En la declaración anterior, las variables reales e, f y g tienen más precisión que las variables reales a, by c. Las variables enteras l, myn pueden almacenar valores más grandes y tener más dígitos para almacenamiento que las variables enteras i, j y k. Aunque esto depende de la máquina.

Ejemplo

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

Cuando compila y ejecuta el programa anterior, produce el siguiente resultado:

default kind for real is 4
default kind for int is 2
extended kind for real is 8
default kind for int is 4

Investigar el tamaño de las variables

Hay una serie de funciones intrínsecas que le permiten interrogar el tamaño de los números.

Por ejemplo, el bit_size(i)La función intrínseca especifica el número de bits utilizados para el almacenamiento. Para números reales, elprecision(x) función intrínseca, devuelve el número de dígitos decimales de precisión, mientras que range(x) La función intrínseca devuelve el rango decimal del exponente.

Ejemplo

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

Cuando compila y ejecuta el programa anterior, produce el siguiente resultado:

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

Obtención del valor bondadoso

Fortran proporciona dos funciones intrínsecas más para obtener el valor de tipo para la precisión requerida de enteros y reales:

  • selected_int_kind (r)
  • selected_real_kind ([p, r])

La función selected_real_kind devuelve un número entero que es el valor de parámetro de tipo de tipo necesario para una precisión decimal dada p y un rango de exponente decimal r. La precisión decimal es el número de dígitos significativos y el rango del exponente decimal especifica el número representable más pequeño y más grande. Por tanto, el intervalo es de 10-r a 10 + r.

Por ejemplo, selected_real_kind (p = 10, r = 99) devuelve el valor de tipo necesario para una precisión de 10 lugares decimales y un rango de al menos 10-99 a 10 + 99.

Ejemplo

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

Cuando compila y ejecuta el programa anterior, produce el siguiente resultado:

selected_real_kind (p = 10, r = 99) 8