Fortran - precyzja liczbowa

Omówiliśmy już, że w starszych wersjach Fortrana były dwa real Typy: domyślny typ rzeczywisty i double precision rodzaj.

Jednak Fortran 90/95 zapewnia większą kontrolę nad precyzją typów danych rzeczywistych i całkowitych poprzez kind specifie.

Rodzaj atrybutu

Różne rodzaje liczb są różnie przechowywane w komputerze. Plikkindatrybut pozwala określić, w jaki sposób liczba jest przechowywana wewnętrznie. Na przykład,

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

W powyższej deklaracji zmienne rzeczywiste e, f ig mają większą dokładność niż zmienne rzeczywiste a, b i c. Zmienne całkowite l, m i n mogą przechowywać większe wartości i mieć więcej cyfr do przechowywania niż zmienne całkowite i, j oraz k. Chociaż jest to zależne od maszyny.

Przykład

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

Kiedy kompilujesz i wykonujesz powyższy program, daje to następujący wynik -

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

Badanie rozmiaru zmiennych

Istnieje wiele funkcji wewnętrznych, które umożliwiają sprawdzenie rozmiaru liczb.

Na przykład bit_size(i)funkcja wewnętrzna określa liczbę bitów używanych do przechowywania. W przypadku liczb rzeczywistych rozszerzenieprecision(x) funkcja intrinsic, zwraca liczbę cyfr dziesiętnych dokładności, podczas gdy range(x) funkcja intrinsic zwraca zakres dziesiętny wykładnika.

Przykład

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

Kiedy kompilujesz i wykonujesz powyższy program, daje to następujący wynik -

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

Uzyskanie życzliwej wartości

Fortran udostępnia dwie dodatkowe funkcje wewnętrzne w celu uzyskania wartości rodzaju dla wymaganej precyzji liczb całkowitych i liczb rzeczywistych -

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

Funkcja selected_real_kind zwraca liczbę całkowitą będącą wartością parametru typu rodzaju niezbędną dla danej dokładności dziesiętnej p i zakresu wykładnika dziesiętnego r. Dokładność dziesiętna to liczba cyfr znaczących, a zakres wykładnika dziesiętnego określa najmniejszą i największą możliwą do przedstawienia liczbę. Zakres wynosi zatem od 10-r do 10 + r.

Na przykład selected_real_kind (p = 10, r = 99) zwraca wartość rodzaju potrzebną do dokładności do 10 miejsc po przecinku i zakresu co najmniej 10-99 do 10 + 99.

Przykład

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

Kiedy kompilujesz i wykonujesz powyższy program, daje to następujący wynik -

selected_real_kind (p = 10, r = 99) 8