Números de Ponto Flutuante#
A representação padrão de números de ponto flutuante é usando precisão simples (usualmente 32 bits / 4 bytes). Para a maioria das aplicações uma precisão maior é necessária. Para esse propósito, um parâmetro de tipo específico pode ser definido. O meio recomendado para definir os tipos do parâmetros é usando
integer, parameter :: dp = selected_real_kind(15)
Para muitos propósitos, é possível inferir diretamente o tipo do parâmetro a partir de um literal como aqui
integer, parameter :: dp = kind(0.0d0)
ou para renomear o tipo do parâmetro importado vindo do módulo iso_fortran_dev
use, intrinsic :: iso_fortran_env, only : dp => real64
Para melhor conhecimento em tipos de parâmetros veja Doctor Fortran in it takes all KINDs.
É recomendado que haja um módulo central para definir os tipos de parâmetros e inclui-los à medida que usa. Um exemplo para tal módulo é dado abaixo
!> Numerical storage size parameters for real and integer values
module kind_parameter
implicit none
public
!> Single precision real numbers, 6 digits, range 10⁻³⁷ to 10³⁷-1; 32 bits
integer, parameter :: sp = selected_real_kind(6, 37)
!> Double precision real numbers, 15 digits, range 10⁻³⁰⁷ to 10³⁰⁷-1; 64 bits
integer, parameter :: dp = selected_real_kind(15, 307)
!> Quadruple precision real numbers, 33 digits, range 10⁻⁴⁹³¹ to 10⁴⁹³¹-1; 128 bits
integer, parameter :: qp = selected_real_kind(33, 4931)
!> Char length for integers, range -2⁷ to 2⁷-1; 8 bits
integer, parameter :: i1 = selected_int_kind(2)
!> Short length for integers, range -2¹⁵ to 2¹⁵-1; 16 bits
integer, parameter :: i2 = selected_int_kind(4)
!> Length of default integers, range -2³¹ to 2³¹-1; 32 bits
integer, parameter :: i4 = selected_int_kind(9)
!> Long length for integers, range -2⁶³ to 2⁶³-1; 64 bits
integer, parameter :: i8 = selected_int_kind(18)
end module kind_parameter
Constantes de ponto flutuante devem sempre ser declaradas incluindo um sufixo de tipo de parâmetro:
real(dp) :: a, b, c
a = 1.0_dp
b = 3.5_dp
c = 1.34e8_dp
É seguro atribuir inteiros para números de ponto flutuante sem perder precisão:
real(dp) :: a
a = 3
Para forçar a divisão de ponto flutuante (em oposição à divisão de inteiro 3/4
igual a 0
), pode-se converter o inteiro para um número de ponto flutuante assim:
real(dp) :: a
a = real(3, dp) / 4 ! 'a' is equal to 0.75_dp
ou simplesmente separe a divisão de inteiros com uma multiplicação por 1.0_dp
real(dp) :: a
a = 3 * 1.0_dp / 4 ! 'a' is equal to 0.75_dp
Para imprimir números de ponto flutuante sem perder precisão use o especificador de formato ilimitado (g0)
ou a representação exponencial (es24.16e3)
. o qual te dará 17 dígitos significativos na saída.