Infinity and negative infinity

Hello, I’m writing an higher level interface to some integration subroutines (as exercise) and was wondering how can I represent infinity and negative infinity in Moderno Fortran. That’s what I’m trying to accomplish:

program main
implicit none
real :: a, b

a = -infinity
b = +infinity

! call integrate(f, a, b, ...
end program
1 Like

The intrinsic module ieee_arithmetic contains some definitions that can be useful.

1 Like

Yes, example:

program ieee
    use, intrinsic :: iso_fortran_env, only: wp=>real64
    use, intrinsic :: ieee_arithmetic
    implicit none

    print *, ieee_value(1.0_wp, ieee_positive_inf)
    print *, ieee_value(1.0_wp, ieee_negative_inf)
end program ieee
$ gfortran -Wall -Wextra -std=f2018 -pedantic ieee_arithmetic.f90 && ./a.out
                  Infinity
                 -Infinity

For ieee_arithmetic you need Fortran>=2003. For iso_fortran_env you need Fortran>=2008.

1 Like

A look a their binary codes:

program ieee
    use, intrinsic :: iso_fortran_env, only: real64, int64
    use, intrinsic :: ieee_arithmetic
    implicit none
    real(real64)   :: r, one
    integer(int64) :: i

    one = 1.0_real64

    r = ieee_value(one, ieee_positive_inf)
    print *, r
    i = transfer(r, i)
    print '(b64.64)', i

    print *, one / r
    i = transfer(one/r, i)
    print '(b64.64)', i
    print *

    r = ieee_value(one, ieee_negative_inf)
    print *, r
    i = transfer(r, i)
    print '(b64.64)', i

    print *, one / r
    i = transfer(one/r, i)
    print '(b64.64)', i
    print *
end program ieee
$ gfortran -Wall -Wextra -std=f2018 -pedantic ieee_arithmetic.f90 && ./a.out
                  Infinity
0111111111110000000000000000000000000000000000000000000000000000
   0.0000000000000000     
0000000000000000000000000000000000000000000000000000000000000000

                 -Infinity
1111111111110000000000000000000000000000000000000000000000000000
  -0.0000000000000000     
1000000000000000000000000000000000000000000000000000000000000000

See:

1 Like

You can also use 2*huge(1.0_wp), where wp is the working precision, as mentioned on comp.lang.fortran. The code

program test ! demonstrate setting and reading infinity
implicit none
integer, parameter :: wp = kind(1.0d0)
real(kind=wp), parameter :: infin = 2*huge(1.0d0)
real(kind=wp) :: x
character (len=20) :: text
print*,infinity(),infin,infin>huge(1.0d0)
text = "Infinity"
read (text,*) x
print*,x
text = "+Inf"
read (text,*) x
print*,x
contains
real(kind=wp) function infinity()
implicit none
real(kind=wp) :: x
x = huge(1.0_wp)
infinity = x + x
end function infinity
end program test

gives output +Inf +Inf T for g95 and the same for gfortran and Intel Fortran, although they output Infinity instead of +Inf. The program also shows that one can read infinity from a string.

1 Like

But be careful, you really need to write exactly the code cited by @Beliavsky:

x = huge(1.0_wp)
infinity = x + x

If you write 2*huge(1.0_wp), the compiler (here gfortran) could complain:

   14 |     r = 2*huge(one)
      |         1
Error: Arithmetic overflow at (1)
1 Like

Relevant stdlib issue: What to do about infinity? · Issue #118 · fortran-lang/stdlib · GitHub

1 Like

I was looking for something short like +inf, -inf, but I think the available solutions are good enough. Thank you everybody. :+1:

In the NLopt optimization library, the documentations suggests to use \pm huge(x) for unbounded dimensions. It kind of makes sense that you would only integrate from/to the largest value which is still representable.

2 Likes