Y a-t-il un moyen standard de vérifier pour Infinite et NaN dans Fortran 90/95?

j'ai essayé de trouver un moyen conforme aux normes pour vérifier les valeurs infinies et NaN dans Fortran 90/95 mais il s'est avéré plus difficile que je pensais.

  • j'ai essayé de créer manuellement des variables Inf et NaN en utilisant la représentation binaire décrite dans IEEE 754, mais je n'ai trouvé aucune fonctionnalité de ce genre.
  • je suis conscient de la valeur intrinsèque ieee_arithmetic module Fortran 2003 avec l' ieee_is_nan() et ieee_is_finite() fonctions intrinsèques. Cependant il n'est pas soutenu par tous les compilateurs ( notamment gfortran à partir de la version 4.9).

la Définition de l'infini et NaN au début comme pinf = 1. / 0 et nan = 0. / 0 me semble hackish et IMHO peut soulever quelques problèmes de construction - par exemple, si certains compilateurs vérifient cela dans le temps de compilation, il faudrait fournir un drapeau spécial.

y a-t-il un moyen que je puisse implémenter dans le standard Fortran 90/95?

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

et <!--6?

18
demandé sur Vladimir F 2013-06-30 15:36:47

6 réponses

la manière simple sans utiliser le ieee_arithmatic est de faire ce qui suit.

Infini: Définissez votre variable infinity = HUGE(dbl_prec_var) (ou, si vous l'avez, un quad précision variable). Ensuite, vous pouvez simplement vérifier pour voir si votre variable est l'infini par if(my_var > infinity).

NAN: C'est encore plus facile. Par définition, NAN n'est pas égal à quoi que ce soit, même à lui-même. Comparez simplement la variable à elle-même:if(my_var /= my_var).

19
répondu Kyle Kanos 2013-06-30 14:50:34

Je n'ai pas assez de réputation pour commenter donc je vais "répondre" à la suggestion de Rick Thompson pour tester l'infini.

if (A-1 .eq. A) 

cela sera aussi vrai si A est un nombre de point flottant très grand, et 1 est inférieur à la précision de A.

Un test simple:

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

sorties:

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!!!
3
répondu Ethan Gutmann 2014-12-31 16:55:34

Non.

les parties saillantes de IEEE_ARITHMETIC for generating / checking for Nan's sont assez faciles à écrire pour gfortran pour une architecture particulière.

2
répondu IanH 2013-06-30 11:47:34

j'ai utilisé:

  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

ceci affichera 'Got a problem' pour nombre = 0.0D0, 1.0D0 / 0.0D0, 0.0D0 / 0.0D0, SQRT (-2.0D0), ainsi que pour les débordements et les sous-écoulements tels que number = EXP(1.0D800) ou nombre = EXP(-1.0D800). Notez que généralement, des choses comme number = EXP(1.0 D-800) vont juste définir number = 1.0 et produire un avertissement au moment de la compilation, mais le programme va imprimer "nous sommes OK", ce que je trouve acceptable.

OL.

1
répondu Otto Linsuain 2016-05-23 14:26:19

Non.

il n'existe pas non plus de méthode de vérification conforme aux normes pour les infinités ou les NaNs dans Fortran 90/95, pas plus qu'il ne peut y avoir de méthode conforme aux normes. Il n'existe aucune façon conforme aux normes de définir l'un ou l'autre de ces quasi-nombres dans le Fortran 90/95.

0
répondu High Performance Mark 2013-06-30 15:43:20

Inf il semble fonctionner que si (A-1 .eq. A) est vrai, alors A est Inf

-2
répondu Rick Thompson 2014-11-12 15:35:23