2009-05-08 23 views
25

Tengo problemas para entender el parámetro kind de Fortran 90. Por lo que puedo decir, no determina la precisión (es decir, flotante o doble) de una variable, ni determina el tipo de una variable.Fortran 90 parámetro tipo

Entonces, ¿qué determina y para qué es exactamente?

+0

¿Se refiere a la notación Kind? – TStamper

Respuesta

3

Del Portland Group Fortran Referencia, el parámetro KIND "especifica una precisión para los tipos de datos intrínsecos". Por lo tanto, en la declaración

real(kind=4) :: float32 
real(kind=8) :: float64 

la variable float64 declarada como una de 8 bytes real (el antiguo Fortran DOUBLE PRECISION) y la variable float32 se declara como 4 bytes real (el antiguo Fortran REAL).

Esto es bueno porque le permite corregir la precisión de sus variables independientemente del compilador y la máquina en la que se está ejecutando. Si está ejecutando un cálculo que requiere más precisión que el tradicional IEEE de precisión simple (que, si está tomando una clase de análisis numérico, es muy probable), pero declara su variable como real :: myVar, estará bien si el compilador establece de manera predeterminada todos los valores real con precisión doble, pero cambiar las opciones del compilador o mover el código a una máquina diferente con diferentes tamaños predeterminados para las variables real y integer dará lugar a sorpresas desagradables (por ejemplo, su solucionador de matriz iterativo arriba).

Fortran también incluye algunas funciones que ayudarán a recoger un parámetro KIND a ser lo que necesita - SELECTED_INT_KIND y SELECTED_REAL_KIND - pero si se acaba de aprender que no me preocuparía por los que están en este punto.

Como mencionaste que estás aprendiendo Fortran como parte de una clase, también deberías ver esta pregunta en Fortran resources y tal vez mirar los manuales de referencia del paquete de compilación que estás utilizando (por ejemplo, Portland Group o Intel) - estos generalmente son de libre acceso.

+0

No, esto no es portátil. No lo recomiendo a los principiantes, por favor. –

44

El KIND de una variable es una etiqueta entera que le dice al compilador cuál de los tipos soportados debería usar.

Mira que aunque es común para el parámetro de tipo en ser el mismo que el número de bytes almacenados en una variable de este tipo, es no requiere por la norma Fortran.

Esto es, en una gran cantidad de sistemas,

REAl(KIND=4) :: xs ! 4 byte ieee float 
REAl(KIND=8) :: xd ! 8 byte ieee float 
REAl(KIND=16) :: xq ! 16 byte ieee float 

pero puede haber compiladores por ejemplo con:

REAL(KIND=1) :: XS ! 4 BYTE FLOAT 
REAL(KIND=2) :: XD ! 8 BYTE FLOAT 
REAL(KIND=3) :: XQ ! 16 BYTE FLOAT 

Del mismo modo para número entero y tipos lógicos.

(Si fui cavando, probablemente podría encontrar ejemplos. Buscar en el comp.lang.fortran grupo Usenet para kind para encontrar ejemplos. La discusión más informada de Fortran se produce allí, con algunas personas de gran experiencia que contribuye.)

Entonces, si no puede contar con un valor de tipo particular que le brinde la misma representación de datos en diferentes plataformas, ¿qué hace?Para eso son las funciones intrínsecas SELECTED_REAL_KIND y SELECTED_INT_KIND. Básicamente, le dice a la función qué tipo de números necesita representar, y devolverá el tipo que necesita usar.

que suelen utilizar este tipo, ya que por lo general me dan 4 bytes y 8 reales de bytes:

!--! specific precisions, usually same as real and double precision 
integer, parameter :: r6 = selected_real_kind(6) 
integer, parameter :: r15 = selected_real_kind(15) 

por lo que podría declarar posteriormente una variable como:

real(kind=r15) :: xd 

Tenga en cuenta que esto puede causar problemas en los que utiliza programas de idiomas mixtos, y necesita especificar absolutamente el número de bytes que ocupan las variables. Si necesita asegurarse, hay aspectos intrínsecos a la consulta que le informarán sobre cada tipo, a partir de los cuales puede deducir la huella de memoria de una variable, su precisión, rango de exponente, etc. O bien, puede volver al estilo de declaración real*4, real*8, etc. no estándar pero común.

Cuando empiezas con un nuevo compilador, vale la pena mirar los valores de compilación específicos para que sepas a qué se enfrenta. Busque en la red kindfinder.f90 para obtener un programa útil que le informará sobre los tipos disponibles para un compilador.

+4

Gracias por señalar que KIND es * no * KIND = - ¿ha visto un compilador moderno donde este es el caso? Ese programa kindfinder.f90 es genial. –

+3

Aparece una búsqueda de usenet: el compilador salford f95 usa los tipos 1, 2 y 3 para las variables de 2 y 4 y 8 bytes; Vi un reclamo de que g77 hizo lo mismo antes de que g95 y gfortran aparecieran; y un informe de que el compilador fortran de NAG tenía un interruptor de compilación que permitía la selección entre el esquema (1,2,3,4) y el esquema (1,2,4,8). Sin duda hay otros. Sí, kindfinder es útil. Puede usarlo para configurar un archivo de módulo específico del sitio que contenga parámetros con nombre para los diferentes tipos, para que sus programas reales no estén repletos de números mágicos no portables. –

+4

Si realmente desea especificar tipos por sus bytes de almacenamiento, Fortran 2003 tiene el enlace ISO_C_Binding, que proporciona valores de tipo correspondientes a los tipos C, algunos de los cuales especifican el tamaño de almacenamiento. Fortran 2008 proporciona tipos en el módulo ISO_FORTRAN_ENV, como el valor de tipo 'real32' para 32 bits,' real64' para 64 bits, etc. Estos tienen la ventaja de ser portátiles, al menos mientras tenga un Fortran 2003 o 2008. compilador. Consulte el manual de gfortran para ver la lista de tipos en estos dos módulos. –

4

Sugiero usar el Fortran 2008 y posterior; INT8, INT16, INT32, INT64, REAL32, REAL64, REAL128. Esto se hace llamando al ISO_FORTRAN_ENV en Fortran 2003 y posteriores. Los parámetros tipo proporcionan una forma incoherente de garantizar que siempre obtenga el número apropiado de representación de bits

+0

'int8' does (si un tipo apropiado está disponible) especifique un parámetro kind. Sospecho que quieres decir que uno debería preferir esto a un número explícito como, digamos 'int (kind = 1)'? [Esto último sería una mala práctica independientemente.] ¿Quizás podrías aclarar? – francescalus

+0

Estoy de acuerdo con su comentario @francescalus – Zeus

+0

@francescalus, ¿no sería útil hacer de esta pregunta una pregunta canónica y tener una sola "respuesta comunitaria" que resuma toda la historia de varias versiones de fortran? A menudo veo código en el que me gustaría referirme a una respuesta canónica tan completa. Este es el mejor lugar aquí, pero la información está completamente distribuida en diferentes respuestas y varios comentarios. (lo siento, esta es la mejor manera en que descubrí que podía contactarte) – kvantour