Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Infinity in Fortran

What is the safest way to set a variable to +Infinity in Fortran? At the moment I am using:

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

but I am wondering if there is a better way?

like image 215
astrofrog Avatar asked Feb 15 '11 22:02

astrofrog


People also ask

How do you write infinity in Fortran?

DIGITAL Fortran 90 identifies infinity values with the letters "Infinity" or asterisks (******) in output statements (depends on field width) or certain hexadecimal values (fraction of 0 and exponent of all 1 values). Not-a-Number (NaN)---An IEEE floating-point bit pattern that represents something other than a number.

Is not a number Fortran?

Not a Number (NaN) is represented by the largest value that the exponent can assume (all ones), and a nonzero fraction. Normalized REAL and DOUBLE PRECISION numbers have an implicit leading bit that provides one more bit of precision than is stored in memory.


3 Answers

If your compiler supports ISO TR 15580 IEEE Arithmetic which is a part of so-called Fortran 2003 standard than you can use procedures from ieee_* modules.

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
like image 120
Wildcat Avatar answered Sep 22 '22 09:09

Wildcat


I would not rely on the compiler to support the IEEE standard and do pretty much what you did, with two changes:

  1. I would not add huge(1.)+huge(1.), since on some compilers you may end up with -huge(1.)+1 --- and this may cause a memory leak (don't know the reason, but it is an experimental fact, so to say).

  2. You are using real types here. I personally prefer to keep all my floating-point numbers as real*8, hence all float constants are qualified with d0, like this: huge(1.d0). This is not a rule, of course; some people prefer using both real-s and real*8-s.

like image 41
ev-br Avatar answered Sep 25 '22 09:09

ev-br


I'm not sure if the solution bellow works on all compilers, but it's a nice mathematical way of reaching infinity as -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

Also works nicely for complex variables.

like image 20
Mikael Fremling Avatar answered Sep 24 '22 09:09

Mikael Fremling