Fortran
Tipos de datos
Buscar..
Tipos intrinsecos
Los siguientes son tipos de datos intrínsecos a Fortran:
integer
real
character
complex
logical
integer
, real
y complex
son tipos numéricos.
character
es un tipo utilizado para almacenar cadenas de caracteres.
logical
se utiliza para almacenar valores binarios .true.
o .false.
.
Todos los tipos intrínsecos numéricos y lógicos se parametrizan utilizando tipos.
integer(kind=specific_kind)
o solo
integer(specific_kind)
donde specific_kind
es un entero llamado constante.
Las variables de caracteres, además de tener un parámetro de clase, también tienen un parámetro de longitud:
character char
declara que char
es una variable de longitud-1 carácter de tipo predeterminado, mientras que
character(len=len) name
declara que el name
es una variable de carácter del tipo predeterminado y la longitud len
. El tipo también puede ser especificado
character(len=len, kind=specific_kind) name
character(kind=specific_kind) char
declara que el name
es un carácter de tipo kind
y longitud len
. char
es una longitud de 1 carácter de tipo kind
.
Alternativamente, la forma obsoleta para la declaración de caracteres.
character*len name
puede verse en el código anterior, declarando que el name
es de longitud len
y tipo de carácter predeterminado.
La declaración de una variable de tipo intrínseco puede ser de la forma anterior, pero también puede usar la forma type(...)
:
integer i
real x
double precision y
es equivalente a (pero se prefiere mucho más que)
type(integer) i
type(real) x
type(double precision) y
Tipos de datos derivados
Definir un nuevo tipo, mytype
:
type :: mytype
integer :: int
real :: float
end type mytype
Declara una variable de tipo mytype :
type(mytype) :: foo
Se puede acceder a los componentes de un tipo derivado con el operador %
1 :
foo%int = 4
foo%float = 3.142
Una característica de Fortran 2003 (aún no implementada por todos los compiladores) permite definir tipos de datos parametrizados:
type, public :: matrix(rows, cols, k)
integer, len :: rows, cols
integer, kind :: k = kind(0.0)
real(kind = k), dimension(rows, cols) :: values
end type matrix
La matrix
tipos derivada tiene tres parámetros de tipo que se enumeran entre paréntesis después del nombre de tipo (son rows
, cols
k
). En la declaración de cada parámetro de tipo debe indicarse si son parámetros de tipo kind ( kind
) o length ( len
).
Los parámetros de tipo de clase, como los de los tipos intrínsecos, deben ser expresiones constantes, mientras que los parámetros de tipo de longitud, como la longitud de una variable de carácter intrínseco, pueden variar durante la ejecución.
Tenga en cuenta que el parámetro k
tiene un valor predeterminado, por lo que se puede proporcionar u omitir cuando se declara una variable de tipo matrix
, de la siguiente manera
type (matrix (55, 65, kind=double)) :: b, c ! default parameter provided
type (matrix (rows=40, cols=50) :: m ! default parameter omitted
El nombre de un tipo derivado no puede ser de doubleprecision
o el mismo que cualquiera de los tipos intrínsecos.
- Muchas personas se preguntan por qué Fortran usa
%
como operador de acceso a componentes, en lugar de los más comunes.
. Esto se debe a.
ya está en la sintaxis del operador, es decir,.not.
,.and.
,.my_own_operator.
.
Precisión de los números en coma flotante.
Los números de punto flotante de tipo real
no pueden tener ningún valor real. Pueden representar números reales hasta cierta cantidad de dígitos decimales.
FORTRAN 77 garantizó dos tipos de punto flotante y las normas más recientes garantizan al menos dos tipos reales. Las variables reales pueden ser declaradas como
real x
double precision y
x
aquí es un tipo real por defecto e y
es un tipo real con mayor precisión decimal que x
. En Fortran 2008, la precisión decimal de y
es al menos 10 y su rango de exponente decimal al menos 37.
real, parameter :: single = 1.12345678901234567890
double precision, parameter :: double = 1.12345678901234567890d0
print *, single
print *, double
huellas dactilares
1.12345684
1.1234567890123457
en compiladores comunes utilizando la configuración por defecto.
Observe la d0
en la constante de doble precisión. Un literal real que contiene d
lugar de e
para denotar el exponente se usa para indicar doble precisión.
! Default single precision constant
1.23e45
! Double precision constant
1.23d45
Fortran 90 introdujo tipos real
parametrizados utilizando tipos. El tipo de un tipo real es un entero llamado constante o constante literal:
real(kind=real_kind) :: x
o solo
real(real_kind) :: x
Esta declaración declara que x
es de tipo real
con una cierta precisión dependiendo del valor de real_kind
.
Los literales de punto flotante se pueden declarar con un tipo específico usando un sufijo
1.23456e78_real_kind
El valor exacto de real_kind
no está estandarizado y difiere de un compilador a otro. Para investigar el tipo de cualquier variable real o constante, la función kind()
se puede usar:
print *, kind(1.0), kind(1.d0)
normalmente se imprimirá
4 8
o
1 2
Dependiendo del compilador.
Los números de clase se pueden establecer de varias maneras:
Precisión simple (por defecto) y doble:
integer, parameter :: single_kind = kind(1.) integer, parameter :: double_kind = kind(1.d0)
Uso de la función intrínseca
selected_real_kind([p, r])
para especificar la precisión decimal requerida. El tipo devuelto tiene una precisión de al menosp
dígitos y permite un exponente de al menosr
.integer, parameter :: single_kind = selected_real_kind( p=6, r=37 ) integer, parameter :: double_kind = selected_real_kind( p=15, r=200 )
A partir de Fortran 2003, las constantes predefinidas están disponibles a través del módulo intrínseco
ISO_C_Binding
para garantizar que las clases reales sean interoperables con los tiposfloat
,double
olong_double
del compilador C que lo acompaña:use ISO_C_Binding integer, parameter :: single_kind = c_float integer, parameter :: double_kind = c_double integer, parameter :: long_kind = c_long_double
A partir de Fortran 2008, las constantes predefinidas están disponibles a través del módulo intrínseco
ISO_Fortran_env
. Estas constantes proporcionan tipos reales con cierto tamaño de almacenamiento en bitsuse ISO_Fortran_env integer, parameter :: single_kind = real32 integer, parameter :: double_kind = real64 integer, parameter :: quadruple_kind = real128
Si cierto tipo no está disponible en el compilador, el valor devuelto por selected_real_kind()
o el valor de la constante entera es -1
.
Parámetros de tipo de longitud asumida y diferida
Las variables de tipo de carácter o de un tipo derivado con parámetro de longitud pueden tener el parámetro de longitud asumido o diferido . El name
variable de caracteres.
character(len=len) name
Es de longitud len
largo de la ejecución. Por el contrario, el especificador de longitud puede ser
character(len=*) ... ! Assumed length
o
character(len=:) ... ! Deferred length
Las variables de longitud asumidas asumen su longitud de otra entidad.
En la funcion
function f(dummy_name)
character(len=*) dummy_name
end function f
el argumento ficticio dummy_name
tiene la longitud del argumento real.
La constante nombrada const_name
en
character(len=*), parameter :: const_name = 'Name from which length is assumed'
tiene la longitud dada por la expresión constante en el lado derecho.
Los parámetros de tipo de longitud diferida pueden variar durante la ejecución. Una variable con longitud diferida debe tener el atributo allocatable
o pointer
character(len=:), allocatable :: alloc_name
character(len=:), pointer :: ptr_name
La longitud de dicha variable se puede establecer de cualquiera de las siguientes maneras
allocate(character(len=5) :: alloc_name, ptr_name)
alloc_name = 'Name' ! Using allocation on intrinsic assignment
ptr_name => another_name ! For given target
Para los tipos derivados con parametrización de longitud, la sintaxis es similar.
type t(len)
integer, len :: len
integer i(len)
end type t
type(t(:)), allocatable :: t1
type(t(5)) t2
call sub(t2)
allocate(type(t(5)) :: t1)
contains
subroutine sub(t2)
type(t(*)), intent(out) :: t2
end subroutine sub
end
Constantes literales
Las unidades de programa a menudo hacen uso de constantes literales. Estos cubren los casos obvios como
print *, "Hello", 1, 1.0
Excepto en un caso, cada constante literal es un escalar que tiene tipo, parámetros de tipo y valor dado por la sintaxis.
Las constantes literales enteras son de la forma
1
-1
-1_1 ! For valid kind parameter 1
1_ik ! For the named constant ik being a valid kind paramter
Las constantes literales reales son de la forma
1.0 ! Default real
1e0 ! Default real using exponent format
1._1 ! Real with kind parameter 1 (if valid)
1.0_sp ! Real with kind paramter named constant sp
1d0 ! Double precision real using exponent format
1e0_dp ! Real with kind named constant dp using exponent format
Las constantes literales complejas son de la forma
(1, 1.) ! Complex with integer and real components, literal constants
(real, imag) ! Complex with named constants as components
Si los componentes real e imaginario son ambos enteros, la constante literal compleja es compleja por defecto, y los componentes enteros se convierten en real por defecto. Si un componente es real, el parámetro kind de la constante literal compleja es el de lo real (y el componente entero se convierte a ese tipo real). Si ambos componentes son reales, la constante literal compleja es de la clase de lo real con la mayor precisión.
Constantes lógicas literales son
.TRUE. ! Default kind, with true value
.FALSE. ! Default kind, with false value
.TRUE._1 ! Of kind 1 (if valid), with true value
.TRUE._lk ! Of kind named constant lk (if valid), with true value
Los valores literales de caracteres difieren ligeramente en concepto, ya que el especificador de clase precede al valor
"Hello" ! Character value of default kind
'Hello' ! Character value of default kind
ck_"Hello" ! Character value of kind ck
"'Bye" ! Default kind character with a '
'''Bye' ! Default kind character with a '
"" ! A zero-length character of default kind
Como se sugirió anteriormente, las constantes literales de los caracteres deben estar delimitadas por apóstrofes o comillas, y los marcadores de inicio y final deben coincidir. Los apóstrofes literales se pueden incluir estando dentro de los delimitadores de comillas o apareciendo duplicados. Lo mismo para las comillas.
Las constantes de BOZ son distintas de las anteriores, ya que solo especifican un valor: no tienen tipo ni parámetro de tipo. Una constante BOZ es un patrón de bits y se especifica como
B'00000' ! A binary bit pattern
B"01010001" ! A binary bit pattern
O'012517' ! An octal bit pattern
O"1267671" ! An octal bit pattern
Z'0A4F' ! A hexadecimal bit pattern
Z"FFFFFF" ! A hexadecimal bit pattern
Las constantes literales de BOZ están limitadas en donde pueden aparecer: como constantes en declaraciones de data
y una selección de procedimientos intrínsecos.
Acceso a subcadenas de caracteres
Para la entidad del personaje.
character(len=5), parameter :: greeting = "Hello"
Una subcadena puede ser referenciada con la sintaxis.
greeting(2:4) ! "ell"
Para acceder a una sola letra no basta con escribir.
greeting(1) ! This isn't the letter "H"
pero
greeting(1:1) ! This is "H"
Para una matriz de caracteres
character(len=5), parameter :: greeting(2) = ["Hello", "Yo! "]
tenemos subcadena de acceso como
greeting(1)(2:4) ! "ell"
pero no podemos hacer referencia a los caracteres no contiguos
greeting(:)(2:4) ! The parent string here is an array
Incluso podemos acceder a subcadenas de constantes literales.
"Hello"(2:4)
Una parte de una variable de carácter también se puede definir utilizando una subcadena como variable. Por ejemplo
integer :: i=1
character :: filename = 'file000.txt'
filename(9:11) = 'dat'
write(filename(5:7), '(I3.3)') i
Accediendo a componentes complejos.
La entidad compleja
complex, parameter :: x = (1., 4.)
Tiene parte real 1.
y parte compleja 4.
.. Podemos acceder a estos componentes individuales como
real(x) ! The real component
aimag(x) ! The complex component
x%re ! The real component
y%im ! The complex component
La forma x%..
es nueva para Fortran 2008 y no es ampliamente compatible con compiladores. Sin embargo, esta forma se puede usar para establecer directamente los componentes individuales de una variable compleja
complex y
y%re = 0.
y%im = 1.
Declaración y atributos.
A lo largo de los temas y ejemplos aquí veremos muchas declaraciones de variables, funciones, etc.
Además de su nombre, los objetos de datos pueden tener atributos . Cubierto en este tema son declaraciones de declaración como
integer, parameter :: single_kind = kind(1.)
que le da al objeto single_kind
el atributo de parameter
(por lo que es una constante con nombre).
Hay muchos otros atributos, como
-
target
-
pointer
-
optional
-
save
Los atributos pueden especificarse con las denominadas declaraciones de especificación de atributos
integer i ! i is an integer (of default kind)...
pointer i ! ... with the POINTER attribute...
optional i ! ... and the OPTIONAL attribute
Sin embargo, generalmente se considera que es mejor evitar el uso de estas declaraciones de especificación de atributos. Para mayor claridad, los atributos pueden especificarse como parte de una sola declaración.
integer, pointer, optional :: i
Esto también reduce la tentación de usar la escritura implícita.
En la mayoría de los casos, en esta documentación de Fortran, se prefiere esta declaración única.