How do I declare the precision of a number to be a

2019-07-31 02:15发布

问题:

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)

回答1:

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


回答2:

Actually many code using this WP approach. Many with select_*_kind intrinsic function. But I think there is a 'easier' way. It's to use default precision without specifying any kind keyword andusing compiler's flag to choose what the default precision is.

Pro is this method is easier if you don't need a precise control of precision on each variable. Con is that will heavily depend on compiler flags, which varies for each compiler or even might not available.

For gfortran, there is more flags -freal4-real8 or -freal4-real16 to promote each explicitly specified lower precision variable to higher precision.