wafelos
wafelos

Reputation: 1

Very small numbers in Fortran

Is it possible to achieve very small numbers in Fortran like 1E-1200? I know how to do it in python, but my code for master's thesis runs too slow. My supervisor recommends me to use Fortran, but I am not sure if this is a problem.

Upvotes: 0

Views: 6115

Answers (3)

Steve Lionel
Steve Lionel

Reputation: 7267

The previous answers suggesting use of REAL128 from ISO_FORTRAN_ENV describe a non-portable solution. What you would get here is a real type whose representation is 128 bits, but that says nothing about the range or precision of the type! For example, some IBM systems have a 128-bit real kind that is actually two doubles with an offset exponent. This gets you more precision but not significantly more range.

The proper way to do this is to use the SELECTED_REAL_KIND intrinsic function to determine the implementation's kind that supports the desired range. For example:

integer, parameter :: bigreal = SELECTED_REAL_KIND(R=1200)
real(KIND=bigreal) :: x

If the implementation doesn't have a real kind that can represent a value with a decimal exponent of plus or minus 1200, you'll get an error, otherwise you'll get the smallest appropriate kind.

You could also specify a P= value in the call to indicate what minimum precision (in decimal digits) you need.

Upvotes: 5

Ross
Ross

Reputation: 2179

The short answer is yes.

Modern compilers typically support so-called quad precision, a 128-bit real. A portable way to access this type is using the ISO_FORTRAN_ENV. Here is a sample program to show how big and small these numbers get:

program main
   use ISO_FORTRAN_ENV, only : REAL32, REAL64, REAL128

   ! -- tiny and huge grab the smallest and largest
   ! -- representable number of each type
   write(*,*) 'Range for REAL32:  ',  tiny(1._REAL32),  huge(1._REAL32)
   write(*,*) 'Range for REAL62:  ',  tiny(1._REAL64),  huge(1._REAL64)
   write(*,*) 'Range for REAL128: ', tiny(1._REAL128), huge(1._REAL128)
end program main

The types REAL32, REAL64, and REAL128 are typically known as single, double, and quad precision. Longer types have a larger range of representable numbers and greater precision.

On my machine with gfortran 4.8, I get:

mach5% gfortran types.f90 && ./a.out
 Range for REAL32:     1.17549435E-38   3.40282347E+38
 Range for REAL62:     2.2250738585072014E-308   1.7976931348623157E+308
 Range for REAL128:    3.36210314311209350626E-4932   1.18973149535723176502E+4932

As you can see, quad precision can represent numbers as small as 3.4E-4932.

Upvotes: 1

tim18
tim18

Reputation: 620

Most Fortran compilers support REAL128 data format which matches IEEE binary128. Some support also REAL80 with similar range, matching C long double. These don't have performance of REAL64 but should be much faster than python.

Upvotes: 0

Related Questions