Fortran - Độ chính xác số

Chúng tôi đã thảo luận rằng, trong các phiên bản cũ hơn của Fortran, có hai real loại: loại thực mặc định và double precision kiểu.

Tuy nhiên, Fortran 90/95 cung cấp nhiều quyền kiểm soát hơn đối với độ chính xác của các kiểu dữ liệu số nguyên và thực thông qua kind cụ thể.

Thuộc tính loại

Các loại số khác nhau được lưu trữ khác nhau bên trong máy tính. Cáckindthuộc tính cho phép bạn chỉ định cách một số được lưu trữ bên trong. Ví dụ,

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

Trong khai báo trên, các biến thực e, f và g có độ chính xác cao hơn các biến thực a, b và c. Các biến số nguyên l, m và n, có thể lưu trữ các giá trị lớn hơn và có nhiều chữ số để lưu trữ hơn các biến số nguyên i, j và k. Mặc dù điều này là phụ thuộc vào máy móc.

Thí dụ

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

Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:

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

Yêu cầu kích thước của các biến

Có một số chức năng nội tại cho phép bạn thẩm vấn kích thước của các con số.

Ví dụ, bit_size(i)hàm nội tại chỉ định số lượng bit được sử dụng để lưu trữ. Đối với số thực,precision(x) hàm nội tại, trả về số chữ số thập phân của độ chính xác, trong khi range(x) hàm nội tại trả về phạm vi thập phân của số mũ.

Thí dụ

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

Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:

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

Đạt được giá trị tử tế

Fortran cung cấp thêm hai hàm nội tại để có được giá trị loại cho độ chính xác cần thiết của số nguyên và số thực -

  • select_int_kind (r)
  • select_real_kind ([p, r])

Hàm select_real_kind trả về một số nguyên là giá trị tham số kiểu loại cần thiết cho độ chính xác thập phân nhất định p và phạm vi số mũ thập phân r. Độ chính xác thập phân là số chữ số có nghĩa và phạm vi số mũ thập phân chỉ định số nhỏ nhất và lớn nhất có thể biểu diễn. Do đó, phạm vi là từ 10-r đến 10 + r.

Ví dụ: select_real_kind (p = 10, r = 99) trả về giá trị loại cần thiết để có độ chính xác 10 chữ số thập phân và phạm vi ít nhất từ ​​10-99 đến 10 + 99.

Thí dụ

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

Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:

selected_real_kind (p = 10, r = 99) 8