Search code examples
arraysfortrandoubleprecisiondimension

Fortran array with explicit double precision


First, I would like to say that I have very little experience with Fortran 77.

I found a precision problem with this code. It uses a implicit double precision (a-h,o-z) definition for all the variables inside the igrf12syn subroutine.

However, when trying to debug this code, I noticed that most values lose precision at some point and using the terminator D0 at the end of the static definitions solve this problem.

But how can I define that the values on my dimension variable gh are explicitly double? I tried to add D0 at the end of the static values in the Data declarations but I got a compiler error.

Edit:

Compiler error after adding the "d0" to the end of a value.

Note that this error does not happen while adding "d0" to other values in the code, outside an array.

igrf.f:527.10:

  data g0/ -31543.d0,-2298., 5922., -677., 2905.,-1061.,  924., 1121
      1
Error: DATA statement at (1) has more variables than values

TL/DR; A Fortran code is having precision problems and I need to add D0 to the end of statically defined values in the code. However, when adding D0 to the values inside the array, I got a compiler error.


Solution

  • Your problem is due to the constrains of fixed-format Fortran, which only allows 72 characters on the line. See for example how g0 is handled in the source:

          dimension gh(3451),g0(120) !... more declarations cut from this
    c
          data g0/ -31543.,-2298., 5922., -677., 2905.,-1061.,  924., 1121., 1900
         1           1022.,-1469., -330., 1256.,    3.,  572.,  523.,  876., 1900
         2            628.,  195.,  660.,  -69., -361., -210.,  134.,  -75., 1900
         3           -184.,  328., -210.,  264.,   53.,    5.,  -33.,  -86., 1900
         4           -124.,  -16.,    3.,   63.,   61.,   -9.,  -11.,   83., 1900
         5           -217.,    2.,  -58.,  -35.,   59.,   36.,  -90.,  -69., 1900
         6             70.,  -55.,  -45.,    0.,  -13.,   34.,  -10.,  -41., 1900
         7             -1.,  -21.,   28.,   18.,  -12.,    6.,  -22.,   11., 1900
         8              8.,    8.,   -4.,  -14.,   -9.,    7.,    1.,  -13., 1900
         9              2.,    5.,   -9.,   16.,    5.,   -5.,    8.,  -18., 1900
         a              8.,   10.,  -20.,    1.,   14.,  -11.,    5.,   12., 1900
         b             -3.,    1.,   -2.,   -2.,    8.,    2.,   10.,   -1., 1900
         c             -2.,   -1.,    2.,   -3.,   -4.,    2.,    2.,    1., 1900
         d             -5.,    2.,   -2.,    6.,    6.,   -4.,    4.,    0., 1900
         e              0.,   -2.,    2.,    4.,    2.,    0.,    0.,   -6./ 1900
    !23456789012345678901234567890123456789012345678901234567890123456789012XXXXX
    !        1         2         3         4         5         6         7  XXXXX
    

    Two things you need to note here. The values 1900 are not part of the array. The 72nd character is the last comma and these remaining numbers are truncated. Secondly, when you add D0 to these numbers you are pushing the last actual value past column 72 where it is then truncated and now you have less values than the variables.

    To fix this you can increase the fixed-form line length with compiler options, but you will need to make sure the trailing values (e.g. 1900) are truncated still. Alternatively you can restructure the data declaration with more continuation lines to fit it all into the 72 column limit. Whatever you choose to do you'll need to make sure the 1900 values are outside the column limit or delete them all.