Положительные / отрицательные постоянные в Фортране
Как я мог получить константы (или parameter
s, я полагаю) это отрицательная и положительная бесконечность в 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