0
program hello
   real(kind=8) :: x
   x=1.000001234567890
   Write(*,'(F10.11)') X
end program Hello

How exactly does the write statement work? I have tried several combination but can't figure it out. And what if I don't know a priori how many decimals a variable has? How can I just print all the number to the last decimal point?

Herman Toothrot
  • 1,463
  • 3
  • 23
  • 53
  • 2
    Have you tried just not specifying a format? For example using `Write(*,*) X` although this is a bit inelegant. Have you read up on [formats](http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap05/format.html)? This is something that should probably be added to the documentation. – d_1999 Sep 02 '16 at 16:47
  • @d_1999 I have tried that gives me 1.0000011920928955, I don't understand – Herman Toothrot Sep 03 '16 at 08:31
  • 1
    `Real(kind=8)` quite possibly does something different you think it does. In particular, it does not specify 8-byte precision nor double precision. http://stackoverflow.com/documentation/fortran/939/data-types/4390/precision-of-floating-point-numbers#t=201609031046388848185 – Vladimir F Героям слава Sep 03 '16 at 10:46
  • 1
    the values are represented in binary, so its an ill posed question to request "all decimals" (obligatory link http://stackoverflow.com/a/588014/1004168). Ultimately you either accepted the list directed (`*`) output, or use a format specification to request the number of digits you want. – agentp Sep 03 '16 at 13:13
  • @agentp good point, I should have said "all significant digits". – Herman Toothrot Sep 05 '16 at 10:11
  • A Fortran constant may have different precision depend on the compiler option. For Intel Fortran compiler, the `-real-size [32/64]` option determines the default precision of a real number if `kind` parameter is not given. So the constant `1.000001234567890` seems to be parsed as a `real(4)` number. – Rubin Dec 10 '18 at 08:32

2 Answers2

2

The following program will print floating-point numbers to standard output without losing any precision.

program main

  use ISO_Fortran_env, only: &
       stdout => OUTPUT_UNIT, &
       compiler_version, &
       compiler_options

    ! Explicit typing only
    implicit none

    ! Variable declarations
    integer, parameter :: SP = selected_real_kind(p=6, r=37)
    integer, parameter :: DP = selected_real_kind(p=15, r=307) 
    real (SP)          :: single
    real (DP)          :: double

    single = 1.000001234567890_SP
    double = 1.000001234567890_DP

    write( stdout, '(e13.6e2)') single
    write( stdout, '(e23.15e3)') double

    write( stdout, '(/4a/)') &
    ' This file was compiled using ', compiler_version(), &
    ' using the options ', compiler_options()

end program main

Take note of how the kind parameters SP and DP are employed to control precision in a portable manner. This program yields:

0.100000E+01
0.100000123456789E+001

This file was compiled using GCC version 6.1.1 20160802 using the options -mtune=generic -march=x86-64 -std=f2008ts
jlokimlin
  • 593
  • 4
  • 9
  • thank you I will try that, although I am surprised that there isn't any other easier way to do it. Is there a way to avoid scientific notation? – Herman Toothrot Sep 02 '16 at 21:46
  • Actually I am not sure that I can use this implementation, I am debugging a huge chunk of code with many variables and I can't change the declaration of all variables. – Herman Toothrot Sep 03 '16 at 08:41
  • @user4050 There is no reason to change any declarations. Perhaps jlokimmlin should explain more explicitly what is the most important part of this answer? – Vladimir F Героям слава Sep 03 '16 at 10:44
1

You main problem was in 'X.Y' that X is the total length, and Y is length to the right of the decimal point. So X > Y, and in your case by 2... Which should be "13.11".

PROGRAM Hello
IMPLICIT NONE
REAL(kind=8) :: x  !Some suggest DOUBLE
x=1.000001234567890
WRITE(*,5) x
5 FORMAT('x=',F14.11)
WRITE(*,6) x             !This make be better for you...
6 FORMAT('x=',0PE22.11)  !This make be better for you...
END PROGRAM Hello
Holmz
  • 714
  • 7
  • 14