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.


  1. 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:

  1. Precisión simple (por defecto) y doble:

    integer, parameter :: single_kind = kind(1.)
    integer, parameter :: double_kind = kind(1.d0)
    
  2. 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 menos p dígitos y permite un exponente de al menos r .

    integer, parameter :: single_kind = selected_real_kind( p=6, r=37 )
    integer, parameter :: double_kind = selected_real_kind( p=15, r=200 )
    
  3. 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 tipos float , double o long_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
    
  4. 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 bits

    use 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.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow