Положительные / отрицательные постоянные в Фортране

Как я мог получить константы (или parameters, я полагаю) это отрицательная и положительная бесконечность в Fortran 2008? Я попробовал следующий код:

program inf
  use, intrinsic :: ieee_arithmetic

  real(8), parameter :: inf_pos = ieee_value(0d0, ieee_positive_inf)
  real(8), parameter :: inf_neg = ieee_value(0d0, ieee_negative_inf)
end program inf

Однако я получаю следующие ошибки:

$ gfortran inf.f08
inf.f08:4:22:

   real(8) :: inf_pos = ieee_value(0d0, ieee_positive_inf)
                  1
Error: Function ‘ieee_value’ in initialization expression at (1) must be an intrinsic function
inf.f08:5:22:

   real(8) :: inf_neg = ieee_value(0d0, ieee_negative_inf)
                  1
Error: Function ‘ieee_value’ in initialization expression at (1) must be an intrinsic function

Несмотря на то, что документация говорит об обратном, кажется, что Gfortran считает, что ieee_value() не свойственно

Есть ли способ получить то, что я пытаюсь сделать?

3 ответа

Решение

Сначала я посмотрю, почему вы не можете использовать ieee_value чтобы дать значение для желаемой именованной константы, тогда я дам плохие новости. Оба интересны (для меня).

ieee_value не является внутренней процедурой. Это процедура встроенного модуля, но, как отмечено в стандарте Fortran 2008 (Примечание 13.25):

Типы и процедуры, определенные в стандартных внутренних модулях, сами по себе не являются внутренними.

Гфортран правильно отметить, что ieee_value не может использоваться в выражении инициализации (константы).

Теперь, если вам нужно инициализировать именованную константу с "бесконечным" значением, есть непереносимые опции: 1.

  • аналогично этому вопросу о NaN, вы можете разработать необходимый битовый шаблон и инициализировать с transfer;
  • Вы можете написать "переполнение" выражения инициализации.

Вы можете обойти непереносимый характер этого с вашей системой сборки и препроцессором.

Тем не менее, вам может не понадобиться бесконечная именованная константа. Модули IEEE легко предоставляют процедуры для "это значение бесконечно?" Или "установить это значение как бесконечное". Ваш компилятор также может иметь "инициализировать переменную в бесконечность" в качестве параметра времени компиляции.


1 Внешние выражения инициализации ограничения на использование ieee_value намного слабее.

Несколько нелегкое решение, которое я придумал, заключалось в упрощении определения функций, которые всегда возвращают положительную и отрицательную бесконечность

program inf
  use, intrinsic :: ieee_arithmetic

  print *, inf_pos()
  print *, inf_neg()

contains
  pure function inf_pos() result(r)
    real(8) :: r
    r = ieee_value(0d0, ieee_positive_inf)
  end function inf_pos

  pure function inf_neg() result(r)
    real(8) :: r
    r = ieee_value(0d0, ieee_negative_inf)
  end function inf_neg
end program inf

Следующее приведет к + и - Бесконечность, однако, должна быть выполнена и не принимается как инициализация непосредственно в объявлении переменной:

program testinf
implicit none
double precision :: x, xiplus, xineg   
x       = HUGE(x)
xiplus  = 2 * x     ! yields +Infinity
xineg   =-2 * x     ! yields -Infinity
write(*,*)x , xiplus, xineg 
end program testinf
Другие вопросы по тегам