2016-07-16 6 views
1

В 2013 году возник вопрос о преобразовании большого рабочего кода с двойной точности в четыре раза: «Converting a working code from double-precision to quadruple-precision: How to read quadruple-precision numbers in FORTRAN from an input file», и консенсусом было объявить переменные с помощью настраиваемого параметра «WP», который указывает «рабочую точность», вместо того, чтобы иметь отдельную версию программы с переменными, объявленными с использованием D + 01, и другую версию с использованием Q + 01. Таким образом, мы можем легко переключаться вперед и назад, определяя WP = real128 или WP = real64 вверху, а остальное не нужно изменять.Как объявить точность числа в качестве настраиваемого параметра?

Но как мы это сделаем?

Я попробовал предложение в ответ на этот вопрос, путем простого кода TEST.F90:

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

скомпилированного:

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

Но это дает:

 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) 

ответ

4

Спецификатор вида должен быть целым параметром - и вы не объявляете его соответствующим образом. Кроме того, implicit none должен идти перед любым объявлением.

Вот рабочая версия решения обеих проблем:

PROGRAM TEST 
    use ISO_FORTRAN_ENV 
    IMPLICIT NONE 
    integer, parameter :: WP= real128 
    real (WP) :: X 

    X= 5.4857990945E-4_WP 
END PROGRAM TEST 
+0

Отлично! Ответ в другом потоке показал, что WP = real128 должен быть прав после использования ISO_FORTRAN_ENV и не отображал часть «integer, parameter ::». Это стало причиной моей проблемы. Спасибо! – user1271772

+3

Возможно, более соблазнительно использовать 'use, intrinsic :: iso_fortran_env, wp => real128', no? – francescalus

+0

Спасибо @francescalus. Каковы преимущества и недостатки двух альтернативных вариантов? – user1271772

0

На самом деле многие кода с использованием этого подхода WP. Многие из них выбирают _ * _ доброкачественную внутреннюю функцию. Но я думаю, что есть «более простой» способ. Он должен использовать точность по умолчанию без указания какого-либо ключевого слова вида и использования флага компилятора для выбора точности по умолчанию.

Про этот метод проще, если вам не нужен точный контроль точности по каждой переменной. Con - это то, что будет сильно зависеть от флагов компилятора, которые различаются для каждого компилятора или даже могут быть недоступны.

Для gfortran существует больше флагов -freal4-real8 или -freal4-real16, чтобы продвигать каждую явно указанную более низкую точность в более высокую точность.

+0

Это на самом деле предпочтительный подход, я думаю. Но я не знаю, как это сделать. – user1271772