Подтвердить что ты не робот

Есть ли стандартный способ проверить Infinite и NaN в Fortran 90/95?

Я пытаюсь найти стандартизованный способ проверить значения Infinite и NaN в Fortran 90/95, но это оказалось сложнее, чем я думал.

  • Я попытался вручную создать переменные Inf и NaN с использованием двоичного представления, описанного в IEEE 754, но я не нашел такой функции.
  • Мне известно о внутреннем модуле ieee_arithmetic в Fortran 2003 с внутренними функциями ieee_is_nan() и ieee_is_finite(). Однако он не поддерживается всеми компиляторами (особенно gfortran с версии 4.9).

Определение бесконечности и NaN в начале, вроде pinf = 1. / 0 и nan = 0. / 0, кажется мне взломанным, и IMHO может вызвать некоторые проблемы с построением - например, если некоторые компиляторы проверяют это во время компиляции, вам нужно будет предоставить специальный флаг.

Есть ли способ, который я могу реализовать в стандартном Fortran 90/95?

function isinf(x)
! Returns .true. if x is infinity, .false. otherwise
...
end function isinf

и isnan()?

4b9b3361

Ответ 1

Простым способом без использования ieee_arithmatic является выполнение следующих действий.

Бесконечность. Определите свою переменную infinity = HUGE(dbl_prec_var) (или, если она у вас есть, переменная точности quad). Затем вы можете просто проверить, не изменилась ли ваша переменная на if(my_var > infinity).

NAN: Это еще проще. По определению, NAN не равна ничему, даже самому себе. Просто сравните переменную с самим собой: if(my_var /= my_var).

Ответ 2

Нет.

Явные части IEEE_ARITHMETIC для генерации/проверки для NaN достаточно легки для записи для gfortran для конкретной архитектуры.

Ответ 3

У меня недостаточно комментариев для комментариев, поэтому я буду "отвечать" на предложение Рика Томпсона для тестирования бесконечности.

if (A-1 .eq. A) 

Это также верно, если A - очень большое число с плавающей запятой, а 1 ниже точности A.

Простой тест:

subroutine test_inf_1(A)
    real, intent(in) :: A
    print*, "Test (A-1 == A)"
    if (A-1 .eq. A) then
        print*, "    INFINITY!!!"
    else
        print*, "    NOT infinite"
    endif
end subroutine

subroutine test_inf_2(A)
    real, intent(in) :: A
    print*, "Test (A > HUGE(A))"
    if (A > HUGE(A)) then
        print*, "    INFINITY!!!"
    else
        print*, "    NOT infinite"
    endif
end subroutine


program test
    real :: A,B

    A=10
    print*, "A = ",A
    call test_inf_1(A)
    call test_inf_2(A)
    print*, ""

    A=1e20
    print*, "A = ",A
    call test_inf_1(A)
    call test_inf_2(A)
    print*, ""

    B=0.0 ! B is necessary to trick gfortran into compiling this
    A=1/B
    print*, "A = ",A
    call test_inf_1(A)
    call test_inf_2(A)
    print*, ""

end program test

выходы:

A =    10.0000000    
Test (A-1 == A)
    NOT infinite
Test (A > HUGE(A))
    NOT infinite

A =    1.00000002E+20
Test (A-1 == A)
    INFINITY!!!
Test (A > HUGE(A))
    NOT infinite

A =          Infinity
Test (A-1 == A)
    INFINITY!!!
Test (A > HUGE(A))
    INFINITY!!!

Ответ 4

Я использовал:

  PROGRAM MYTEST
  USE, INTRINSIC :: IEEE_ARITHMETIC, ONLY: IEEE_IS_FINITE      
  DOUBLE PRECISION :: number, test
  number = 'the expression to test'
  test = number/number
  IF (IEEE_IS_FINITE(test)) THEN
     WRITE(*,*) 'We are OK'
  ELSE
     WRITE(*,*) 'Got a problem'
  END IF         
     WRITE(*,*) number, test
  END PROGRAM MYTEST

Это будет печатать "Задача" для числа = 0.0D0, 1.0D0/0.0D0, 0.0D0/0.0D0, SQRT (-2.0D0), а также для переполнений и недочетов, таких как number = EXP (1.0D800 ) или number = EXP (-1.0D800). Обратите внимание, что в целом такие вещи, как number = EXP (1.0D-800), просто устанавливают число = 1.0 и выдают предупреждение во время компиляции, но программа будет печатать "Мы в порядке", что я считаю приемлемым.

OL.

Ответ 5

Нет.

Также не существует стандартного способа проверки бесконечности или NaN в Fortran 90/95, а также не может быть стандартно. Не существует стандартного способа определения любого из этих квази чисел в Fortran 90/95.

Ответ 6

Для Inf, кажется, работает, что если (A-1. Aq. A) истинно, то A является Inf