descargar - fortran 95 download
¿Hay alguna forma estándar de verificar si hay Infinite y NaN en Fortran 90/95? (6)
He estado tratando de encontrar una forma compatible con los estándares para verificar los valores de Infinite y NaN en Fortran 90/95, pero resultó ser más difícil de lo que pensaba.
- Intenté crear manualmente las variables Inf y NaN utilizando la representación binaria descrita en IEEE 754, pero no encontré tal funcionalidad.
- Soy consciente del módulo intrínseco
ieee_arithmetic
en Fortran 2003 con las funciones intrínsecasieee_is_nan()
yieee_is_finite()
. Sin embargo, no es compatible con todos los compiladores ( especialmente gfortran a partir de la versión 4.9).
Definir el infinito y el NaN al principio como pinf = 1. / 0
y nan = 0. / 0
parece difícil y el IMHO puede plantear algunos problemas de construcción, por ejemplo, si algunos compiladores comprueban esto en tiempo de compilación, uno tendría que proporcionar un especial bandera.
¿Hay alguna manera de implementar el estándar Fortran 90/95?
function isinf(x)
! Returns .true. if x is infinity, .false. otherwise
...
end function isinf
y isnan()
?
He utilizado:
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
Esto imprimirá ''Tengo un problema'' para el número = 0.0D0, 1.0D0 / 0.0D0, 0.0D0 / 0.0D0, SQRT (-2.0D0), y también para desbordamientos y subflujos como el número = EXP (1.0D800) o número = EXP (-1.0D800). Tenga en cuenta que, en general, cosas como el número = EXP (1.0D-800) simplemente configurarán el número = 1.0 y producirán una advertencia en el momento de la compilación, pero el programa imprimirá "Estamos bien", lo cual me parece aceptable.
OL
La manera simple sin usar ieee_arithmatic
es hacer lo siguiente.
Infinito : defina su variable infinity = HUGE(dbl_prec_var)
(o, si lo tiene, una variable de precisión de cuadrante). Luego, simplemente puedes verificar si tu variable es infinita por if(my_var > infinity)
.
NAN : Esto es aún más fácil. Por definición, NAN no es igual a nada, incluso a sí mismo. Simplemente compare la variable a sí misma: if(my_var /= my_var)
.
No tengo suficiente representante para comentar, así que "responderé" con respecto a la sugerencia de Rick Thompson para probar el infinito.
if (A-1 .eq. A)
Esto también será cierto si A es un número de punto flotante muy grande y 1
está por debajo de la precisión de A.
Una prueba 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
salidas:
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!!!
No.
Las partes salientes de IEEE_ARITHMETIC para generar / verificar los NaN son fáciles de escribir para gfortran para una arquitectura particular.
No.
Tampoco existe una manera de verificar los infinitos o NaN que cumpla con las normas en Fortran 90/95, ni puede haber una manera que cumpla con las normas. No existe una manera que cumpla con los estándares para definir cualquiera de estos cuasi números en Fortran 90/95.
Para Inf parece funcionar que si (A-1 .eq. A) es verdadero, entonces A es Inf