Question

Quel est le moyen le plus sûr de définir une variable sur + Infinity dans FORTRAN? Pour le moment, j'utilise:

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

Mais je me demande s'il y a une meilleure façon?

Était-ce utile?

La solution

Si votre compilateur les soutiens ISO TR 15580 IEEE Arithmétique qui fait partie de la norme dite FORTRAN 2003 que vous pouvez utiliser les procédures des modules 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

Autres conseils

Je ne compterais pas sur le compilateur pour soutenir la norme IEEE et faire à peu près ce que vous avez fait, avec deux changements:

  1. Je n'aimerais pas huge(1.)+huge(1.), car sur certains compilateurs, vous pouvez vous retrouver avec -huge(1.)+1 --- Et cela peut provoquer une fuite de mémoire (je ne connais pas la raison, mais c'est un fait expérimental, pour ainsi dire).

  2. Vous utilisez real types ici. Je préfère personnellement garder tous mes nombres à virgule flottante comme real*8, par conséquent, toutes les constantes flottantes sont qualifiées avec d0, comme ça: huge(1.d0). Ce n'est pas une règle, bien sûr; Certaines personnes préfèrent utiliser les deux real-le sable real*8-S.

Je ne sais pas pour la plus sûre, mais je peux vous offrir une méthode alternative. J'ai appris à le faire de cette façon:

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

Si vous utilisez des valeurs exceptionnelles dans les expressions (je ne pense pas que cela soit généralement conseillé), vous devez prêter une attention particulière à la façon dont votre compilateur les gère, vous pourriez obtenir des résultats inattendus autrement.

Je ne sais pas si la solution ci-dessous fonctionne sur tous les compilateurs, mais c'est une belle façon mathématique d'atteindre l'infini comme -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

Fonctionne également bien pour des variables complexes.

Cela semble fonctionner pour moi. Définir un paramètre

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

Ensuite, utilisez-le dans les tests.

  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(*,*)

Lorsqu'il est compilé avec Ifort & Run, je reçois

sng = inf
dbl1 = inf
dbl2 = inf
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top