Fortran - Números

Los números en Fortran están representados por tres tipos de datos intrínsecos:

  • Tipo entero
  • Tipo real
  • Tipo complejo

Tipo entero

Los tipos enteros solo pueden contener valores enteros. El siguiente ejemplo extrae el valor más grande que podría mantenerse en un entero de cuatro bytes habitual:

program testingInt
implicit none

   integer :: largeval
   print *, huge(largeval)
   
end program testingInt

Cuando compila y ejecuta el programa anterior, produce el siguiente resultado:

2147483647

Tenga en cuenta que el huge()La función da el número más grande que puede contener el tipo de datos entero específico. También puede especificar el número de bytes usando elkindespecificador. El siguiente ejemplo demuestra esto:

program testingInt
implicit none

   !two byte integer
   integer(kind = 2) :: shortval
   
   !four byte integer
   integer(kind = 4) :: longval
   
   !eight byte integer
   integer(kind = 8) :: verylongval
   
   !sixteen byte integer
   integer(kind = 16) :: veryverylongval
   
   !default integer 
   integer :: defval
        
   print *, huge(shortval)
   print *, huge(longval)
   print *, huge(verylongval)
   print *, huge(veryverylongval)
   print *, huge(defval)
   
end program testingInt

Cuando compila y ejecuta el programa anterior, produce el siguiente resultado:

32767
2147483647
9223372036854775807
170141183460469231731687303715884105727
2147483647

Tipo real

Almacena los números de punto flotante, como 2.0, 3.1415, -100.876, etc.

Tradicionalmente había dos real tipos: el tipo real predeterminado y double precision tipo.

Sin embargo, Fortran 90/95 proporciona más control sobre la precisión de los tipos de datos reales y enteros a través del kind especificador, que estudiaremos en breve.

El siguiente ejemplo muestra el uso de tipos de datos reales:

program division   
implicit none

   ! Define real variables   
   real :: p, q, realRes 
   
   ! Define integer variables  
   integer :: i, j, intRes  
   
   ! Assigning  values   
   p = 2.0 
   q = 3.0    
   i = 2 
   j = 3  
   
   ! floating point division
   realRes = p/q  
   intRes = i/j
   
   print *, realRes
   print *, intRes
   
end program division

Cuando compila y ejecuta el programa anterior, produce el siguiente resultado:

0.666666687    
0

Tipo complejo

Se utiliza para almacenar números complejos. Un número complejo tiene dos partes: la parte real y la parte imaginaria. Dos unidades de almacenamiento numérico consecutivas almacenan estas dos partes.

Por ejemplo, el número complejo (3.0, -5.0) es igual a 3.0 - 5.0i

La función genérica cmplx()crea un número complejo. Produce un resultado cuyas partes reales e imaginarias son de precisión simple, independientemente del tipo de argumentos de entrada.

program createComplex
implicit none

   integer :: i = 10
   real :: x = 5.17
   print *, cmplx(i, x)
   
end program createComplex

Cuando compila y ejecuta el programa anterior, produce el siguiente resultado:

(10.0000000, 5.17000008)

El siguiente programa demuestra la aritmética de números complejos:

program ComplexArithmatic
implicit none

   complex, parameter :: i = (0, 1)   ! sqrt(-1)   
   complex :: x, y, z 
   
   x = (7, 8); 
   y = (5, -7)   
   write(*,*) i * x * y
   
   z = x + y
   print *, "z = x + y = ", z
   
   z = x - y
   print *, "z = x - y = ", z 
   
   z = x * y
   print *, "z = x * y = ", z 
   
   z = x / y
   print *, "z = x / y = ", z 
   
end program ComplexArithmatic

Cuando compila y ejecuta el programa anterior, produce el siguiente resultado:

(9.00000000, 91.0000000)
z = x + y = (12.0000000, 1.00000000)
z = x - y = (2.00000000, 15.0000000)
z = x * y = (91.0000000, -9.00000000)
z = x / y = (-0.283783793, 1.20270276)

El rango, la precisión y el tamaño de los números

El rango de números enteros, la precisión y el tamaño de los números de coma flotante depende del número de bits asignados al tipo de datos específico.

La siguiente tabla muestra el número de bits y el rango para enteros:

Número de bits Valor máximo Razón
64 9.223.372.036.854.774.807 (2 ** 63) –1
32 2,147,483,647 (2 ** 31) –1

La siguiente tabla muestra el número de bits, el valor más pequeño y más grande, y la precisión de los números reales.

Número de bits Mayor valor Valor más pequeño Precisión
64 0.8E + 308 0,5E – 308 15-18
32 1.7E + 38 0.3E – 38 6-9

Los siguientes ejemplos demuestran esto:

program rangePrecision
implicit none

   real:: x, y, z
   x = 1.5e+40
   y = 3.73e+40
   z = x * y 
   print *, z
   
end program rangePrecision

Cuando compila y ejecuta el programa anterior, produce el siguiente resultado:

x = 1.5e+40
          1
Error : Real constant overflows its kind at (1)
main.f95:5.12:

y = 3.73e+40
           1
Error : Real constant overflows its kind at (1)

Ahora usemos un número más pequeño:

program rangePrecision
implicit none

   real:: x, y, z
   x = 1.5e+20
   y = 3.73e+20
   z = x * y 
   print *, z
   
   z = x/y
   print *, z
   
end program rangePrecision

Cuando compila y ejecuta el programa anterior, produce el siguiente resultado:

Infinity
0.402144760

Ahora veamos el desbordamiento -

program rangePrecision
implicit none

   real:: x, y, z
   x = 1.5e-30
   y = 3.73e-60
   z = x * y 
   print *, z
   
   z = x/y
   print *, z

end program rangePrecision

Cuando compila y ejecuta el programa anterior, produce el siguiente resultado:

y = 3.73e-60
           1
Warning : Real constant underflows its kind at (1)

Executing the program....
$demo 

0.00000000E+00
Infinity

El especificador amable

En la programación científica, a menudo es necesario conocer el rango y la precisión de los datos de la plataforma de hardware en la que se está trabajando.

La función intrínseca kind() le permite consultar los detalles de las representaciones de datos del hardware antes de ejecutar un programa.

program kindCheck
implicit none
   
   integer :: i 
   real :: r 
   complex :: cp 
   print *,' Integer ', kind(i) 
   print *,' Real ', kind(r) 
   print *,' Complex ', kind(cp) 
   
end program kindCheck

Cuando compila y ejecuta el programa anterior, produce el siguiente resultado:

Integer 4
Real 4
Complex 4

También puede verificar el tipo de todos los tipos de datos:

program checkKind
implicit none

   integer :: i 
   real :: r 
   character :: c 
   logical :: lg 
   complex :: cp 
   
   print *,' Integer ', kind(i) 
   print *,' Real ', kind(r) 
   print *,' Complex ', kind(cp)
   print *,' Character ', kind(c) 
   print *,' Logical ', kind(lg)
   
end program checkKind

Cuando compila y ejecuta el programa anterior, produce el siguiente resultado:

Integer 4
Real 4
Complex 4
Character 1
Logical 4