Search code examples
gccfortranprecisiongfortranarbitrary-precision

How do I declare the precision of a number to be an adjustable parameter?


In 2013 there was a question on converting a big working code from double to quadruple precision: "Converting a working code from double-precision to quadruple-precision: How to read quadruple-precision numbers in FORTRAN from an input file", and the consensus was to declare variables using an adjustable parameter "WP" that specifies the "working precision", instead of having a separate version of the program with variables declared using D+01, and another version using Q+01. This way we can easily switch back and forth by defining WP=real128 or WP=real64 at the top, and the rest doesn't need to change.

But how do we do this?

I tried the suggestion in the answer to that question, by making a simple code TEST.F90:

  PROGRAM TEST
  use ISO_FORTRAN_ENV
  WP= real128
  IMPLICIT NONE
  real (WP) ::  X
  X= 5.4857990945E-4_WP
  END PROGRAM TEST

compiled with:

~/gcc-4.6/bin/gfortran -o tst.x TEST.F90

But it gives:

      IMPLICIT NONE
                   1
Error: Unexpected IMPLICIT NONE statement at (1)
QLEVEL16.F90:5.12:

      real (WP) ::  MEL 
            1
Error: Parameter 'wp' at (1) has not been declared or is a variable, which does not reduce to a constant expression
QLEVEL16.F90:6.29:

      MEL= 5.4857990945E-4_WP
                             1
Error: Missing kind-parameter at (1)

Solution

  • The kind specifier must be an integer parameter - and you do not declare it appropriately. Furthermore, implicit none must go before any declaration.

    Here is a working version addressing both issues:

    PROGRAM TEST
      use ISO_FORTRAN_ENV
      IMPLICIT NONE
      integer, parameter :: WP= real128
      real (WP) ::  X
    
      X= 5.4857990945E-4_WP
    END PROGRAM TEST