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