Fortran - Precisão Numérica
Já discutimos que, nas versões mais antigas do Fortran, havia dois real tipos: o tipo real padrão e double precision tipo.
No entanto, o Fortran 90/95 fornece mais controle sobre a precisão dos tipos de dados reais e inteiros por meio do kind specifie.
O atributo de tipo
Diferentes tipos de números são armazenados de forma diferente dentro do computador. okindatributo permite que você especifique como um número é armazenado internamente. Por exemplo,
real, kind = 2 :: a, b, c
real, kind = 4 :: e, f, g
integer, kind = 2 :: i, j, k
integer, kind = 3 :: l, m, n
Na declaração acima, as variáveis reais e, f e g têm mais precisão do que as variáveis reais a, be c. As variáveis inteiras l, m e n podem armazenar valores maiores e ter mais dígitos para armazenamento do que as variáveis inteiras i, j e k. Embora isso seja dependente da máquina.
Exemplo
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 você compila e executa o programa acima, ele produz o seguinte 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
Perguntando sobre o tamanho das variáveis
Existem várias funções intrínsecas que permitem interrogar o tamanho dos números.
Por exemplo, o bit_size(i)função intrínseca especifica o número de bits usados para armazenamento. Para números reais, oprecision(x) função intrínseca, retorna o número de dígitos decimais de precisão, enquanto o range(x) função intrínseca retorna o intervalo decimal do expoente.
Exemplo
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 você compila e executa o programa acima, ele produz o seguinte 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
Obtendo o valor da espécie
Fortran fornece mais duas funções intrínsecas para obter o valor do tipo para a precisão necessária de inteiros e reais -
- selected_int_kind (r)
- selected_real_kind ([p, r])
A função selected_real_kind retorna um número inteiro que é o valor do parâmetro de tipo necessário para uma determinada precisão decimal p e intervalo de expoente decimal r. A precisão decimal é o número de dígitos significativos e o intervalo do expoente decimal especifica o menor e o maior número representável. O intervalo é, portanto, de 10-r a 10 + r.
Por exemplo, selected_real_kind (p = 10, r = 99) retorna o valor do tipo necessário para uma precisão de 10 casas decimais e um intervalo de pelo menos 10-99 a 10 + 99.
Exemplo
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 você compila e executa o programa acima, ele produz o seguinte resultado -
selected_real_kind (p = 10, r = 99) 8