Бесконечность в Фортране - PullRequest
8 голосов
/ 16 февраля 2011

Какой самый безопасный способ установить переменную + Infinity в Fortran?На данный момент я использую:

program test
  implicit none
  print *,infinity()
contains
  real function infinity()
    implicit none
    real :: x
    x = huge(1.)
    infinity = x + x
  end function infinity
end program test

, но мне интересно, есть ли лучший способ?

Ответы [ 5 ]

9 голосов
/ 16 февраля 2011

Если ваш компилятор поддерживает Арифметику IEEE ISO TR 15580, которая является частью так называемого стандарта Fortran 2003, чем вы можете использовать процедуры из модулей ieee_ *.

PROGRAM main

  USE ieee_arithmetic

  IMPLICIT NONE

  REAL :: r

  IF (ieee_support_inf(r)) THEN
    r = ieee_value(r,  ieee_negative_inf)
  END IF

  PRINT *, r

END PROGRAM main
0 голосов
/ 02 февраля 2015

Кажется, это работает для меня. Определить параметр

double precision,parameter :: inf = 1.d0/0.d0

Затем используйте его в тестах if.

  real :: sng
  double precision :: dbl1,dbl2

  sng = 1.0/0.0
  dbl1 = 1.d0/0.d0
  dbl2 = -log(0.d0)

  if(sng == inf) write(*,*)"sng = inf"
  if(dbl1 == inf) write(*,*)"dbl1 = inf"
  if(dbl2 == inf) write(*,*)"dbl2 = inf"
  read(*,*)

При компиляции с помощью ifort & run я получаю

sng = inf
dbl1 = inf
dbl2 = inf
0 голосов
/ 23 сентября 2014

Я не уверен, работает ли приведенное ниже решение на всех компиляторах, но это хороший математический способ достижения бесконечности как -log (0).

program test
  implicit none
  print *,infinity()
contains
  real function infinity()
    implicit none
    real :: x
    x = 0
    infinity=-log(x)
  end function infinity
end program test

Также хорошо работает для сложных переменных.

0 голосов
/ 16 февраля 2011

Я бы не стал полагаться на то, что компилятор поддерживает стандарт IEEE, и сделал бы в значительной степени то, что вы сделали, с двумя изменениями:

  1. Я бы не стал добавлять huge(1.)+huge(1.), поскольку на некоторых компиляторах вы можете получить -huge(1.)+1 --- и это может привести к утечке памяти (не знаю причину, но это экспериментальный факт так сказать).

  2. Вы используете real типы здесь. Лично я предпочитаю, чтобы все мои числа с плавающей запятой были real*8, поэтому все константы с плавающей запятой имеют квалификацию d0, например: huge(1.d0). Это не правило, конечно; некоторые люди предпочитают использовать real -s и real*8 -s.

0 голосов
/ 16 февраля 2011

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

PROGRAM infinity
  IMPLICIT NONE
  INTEGER :: inf
  REAL :: infi
  EQUIVALENCE (inf,infi) !Stores two variable at the same address
  DATA inf/z'7f800000'/ !Hex for +Infinity
  WRITE(*,*)infi
END PROGRAM infinity

Если вы используете исключительные значения в выражениях (я не думаю, что это вообще рекомендуется), вам следует внимательно следить за тем, как ваш компилятор обрабатывает их, в противном случае вы можете получить неожиданные результаты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...