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.
Is there a portable way to output a real
to full precision? I'm specifically asking for double-precision real
s, 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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With