Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is a portable format to fully express a double-precision value in Fortran?

Suppose I wish to write a double-precision value to an ASCII file to its full precision in a portable manner. (Obviously raw binary output is the most compact way to express a number, but that's not what I'm asking here.)

I want another program, written in e.g. MATLAB or Python, to be able to read the file and store the same exact value as the Fortran program has internally.

The default ASCII output is simply done as follows:

program main
   use, intrinsic :: ISO_FORTRAN_ENV, only : dp=>REAL64, stdout=>OUTPUT_UNIT
   implicit none

   real(kind=dp), parameter :: pi = 3.141592653589793238462643383279502884197_dp

   write(stdout,*) pi            ! Test the default format 
   write(stdout,'(f)') pi        ! Test the specific decimal default format
   write(stdout,'(f20.15)') pi   ! Probably sufficient precision...
   write(stdout,'(f30.20)') pi   ! EXCESSIVE PRECISION!

end program main

I understand that different compilers may have different formatting defaults and requirements. For instance, ifort compiles the above example without issue and produces the following output:

   3.14159265358979
       3.1415926535897931
   3.141592653589793
        3.14159265358979311600

gfortran (gcc version 4.8.2), on the other hand, requires a width for the second output statement, so compilation fails. Commenting out that second output statement '(f)' allows compilation, and the result (with a blank line added here) is:

   3.1415926535897931

   3.141592653589793
        3.14159265358979311600

I do not have access to nagfor and have not installed any other Fortran compilers, so I do not test them here.

You'll notice that the results vary. I expect that none of the results are exact, but rather exact to machine precision. Of course ~15 digits is acceptable for most purposes, but I'm curious about full-precision output so a number can be passed between programs via ASCII output without loss of precision.

My Question

Is there a portable way to output a real to full precision? I'm specifically asking for double-precision reals, but if there's a kind-independent way to do that, I'd give preference to that answer. Presumably one could use the "EXCESSIVE PRECISION" approach, but bonus points for conciseness, too.

like image 800
jvriesem Avatar asked May 16 '18 19:05

jvriesem


1 Answers

It's generally the case that if you have three more decimal digits than the datatype can represent, you won't lose any bits. So for double precision IEEE float, that would be 18 digits.

Your second format uses a non-standard syntax that ifort supports but gfortran does not. I don't recommend its use.

Fortran 2018 offers "hex format" for real values, that preserves all the bits, but I think only C/C++ understands it.

like image 114
Steve Lionel Avatar answered Sep 28 '22 00:09

Steve Lionel