问题
How could I get constants (or parameter
s, I suppose) that are negative and positive infinity in Fortran 2008? I tried the following code:
program inf
use, intrinsic :: ieee_arithmetic
real(8), parameter :: inf_pos = ieee_value(0d0, ieee_positive_inf)
real(8), parameter :: inf_neg = ieee_value(0d0, ieee_negative_inf)
end program inf
However, I get the following errors:
$ gfortran inf.f08
inf.f08:4:22:
real(8) :: inf_pos = ieee_value(0d0, ieee_positive_inf)
1
Error: Function ‘ieee_value’ in initialization expression at (1) must be an intrinsic function
inf.f08:5:22:
real(8) :: inf_neg = ieee_value(0d0, ieee_negative_inf)
1
Error: Function ‘ieee_value’ in initialization expression at (1) must be an intrinsic function
Despite documentation saying otherwise, it seems that gfortran thinks that ieee_value()
isn't intrinsic.
Is there anyway to get what I'm trying to do?
回答1:
I'll first look at why you can't use ieee_value
to give the value for your desired named constant, then I'll give bad news. Both are interesting (to me).
ieee_value
isn't an intrinsic procedure. It's a procedure in an intrinsic module but as the Fortran 2008 standard notes (Note 13.25):
The types and procedures defined in standard intrinsic modules are not themselves intrinsic.
gfortran is correct to note that ieee_value
may not be used in an initialization (constant) expression.
Now, if you need to initialize a named constant with an "infinite" value there are non-portable options:1.
- similar to this question about NaNs you can work out the required bit pattern and initialize with
transfer
; - you may be able to write an "overflowing" initialization expression.
You can work around the non-portable nature of this with your build system and pre-processor.
That all said, you may not need to have an infinite named constant. The IEEE modules easily provide procedures for "is this value infinite?", or "set this value to be infinite". Your compiler may also have "initialize variable to infinity" as a compile-time option.
1 Outside initialization expressions the restrictions on using ieee_value
are much looser.
回答2:
The somewhat inelegant solution I came up with was to simplify define functions which always return positive and negative infinity
program inf
use, intrinsic :: ieee_arithmetic
print *, inf_pos()
print *, inf_neg()
contains
pure function inf_pos() result(r)
real(8) :: r
r = ieee_value(0d0, ieee_positive_inf)
end function inf_pos
pure function inf_neg() result(r)
real(8) :: r
r = ieee_value(0d0, ieee_negative_inf)
end function inf_neg
end program inf
回答3:
The following would yield + and - Infinity, however, must be executed and is not accepted as initialisation directly in the variable declaration:
program testinf
implicit none
double precision :: x, xiplus, xineg
x = HUGE(x)
xiplus = 2 * x ! yields +Infinity
xineg =-2 * x ! yields -Infinity
write(*,*)x , xiplus, xineg
end program testinf
来源:https://stackoverflow.com/questions/50611059/positive-negative-infinity-constants-in-fortran