Fortran: Fortran 2003: Intrinsische Module
<<< zur Fortran-Startseite | |
<< Fortran 2003 | Bibliotheken >> |
< Intrinsische Funktionen und Subroutinen | OOP > |
Grundlegendes
BearbeitenModule gab es bereits mit Fortran 90/95. Neu in Fortran 2003 sind die sogenannten "intrinsischen Module". Das sind jene Module, die bereits standardmäßig von Fortran-2003-Compilern bereitgestellt werden. Werden Datenelemente oder Funktionen aus solchen intrinsischen Modulen benötigt, so ist das entsprechende Modul mittels
use, intrinsic :: modulname |
in die jeweilige Programmeinheit einzubinden.
Der Unterschied zu konventionellen (nonintrinsischen) Modulen ist das Wörtchen intrinsic
, das dem Compiler mitteilt, dass er das Modul bereits mitbringt und nicht irgendwo extern danach suchen soll. Wird nach dem use
-Schlüsselwort kein entsprechendes Attribut oder das non_intrinsic
-Attribut angegeben, so zeigt dies an, dass ein nonintrinsisches Modul benutzt wird.
Das intrinsische Modul iso_fortran_env
Bearbeiten
Das iso_fortran_env
-Modul enthält einige Fortran-umgebungsspezifische Konstanten.
Beispiel:
Fortran 2003 (oder neuer)-Code |
program bsp use, intrinsic :: iso_fortran_env implicit none write( *, * ) INPUT_UNIT write( *, * ) OUTPUT_UNIT write( *, * ) ERROR_UNIT write( *, * ) IOSTAT_END write( *, * ) IOSTAT_EOR write( *, * ) NUMERIC_STORAGE_SIZE write( *, * ) CHARACTER_STORAGE_SIZE write( *, * ) FILE_STORAGE_SIZE ! Ausgabe, z.B.: ! 5 ! 6 ! 0 ! -1 ! -2 ! 32 ! 8 ! 8 end program bsp |
Erläuterung:
Konstante | Anmerkung |
---|---|
INPUT_UNIT | Standard-Eingabeeinheit (entspricht unit=* bei read )
|
OUTPUT_UNIT | Standard-Ausgabeeinheit (entspricht unit=* bei write )
|
ERROR_UNIT | Standard-Fehlerausgabeeinheit |
IOSTAT_END | end-of-file (EOF) |
IOSTAT_EOR | end-of-record (EOR) |
NUMERIC_STORAGE_SIZE | Speicherplatzbedarf (in bits) |
CHARACTER_STORAGE_SIZE | Speicherplatzbedarf (in bits) |
FILE_STORAGE_SIZE | Speicherplatzbedarf (in bits) |
All diese Konstanten sind Skalare vom Datentyp integer
.
Des Weiteren können mittels INTEGER_KINDS, REAL_KINDS, LOGICAL_KINDS
und CHARACTER_KINDS
die auf dem jeweiligen System verfügbaren kind-Parameter ermittelt werden.
Beispiel:
Fortran 2003 (oder neuer)-Code |
program bsp use, intrinsic :: iso_fortran_env implicit none print *, "integer_kinds = ", INTEGER_KINDS print *, "real_kinds = ", REAL_KINDS print *, "logical_kinds = ", LOGICAL_KINDS print *, "character_kinds = ", CHARACTER_KINDS ! Ausgabe, z.B.: ! integer_kinds = 1 2 4 8 ! real_kinds = 4 8 10 16 ! logical_kinds = 1 2 4 8 ! character_kinds = 1 4 end program bsp |
Beispiel (Ausgabe eines Unicode-Zeichens, siehe auch Programming in Modern Fortran - Unicode):
Fortran 2003 (oder neuer)-Code |
program bsp use, intrinsic :: iso_fortran_env, only: output_unit implicit none integer, parameter :: iso_10646 = selected_char_kind('ISO_10646') character(kind=iso_10646) :: c ! Das €-Zeichen c = iso_10646_'\u20AC' open (output_unit, encoding='UTF-8') print *, c ! Ausgabe: ! € end program bsp |
Compiler-Aufruf:
gfortran.exe bsp.f08 -fbackslash
Die Compiler-Option -fbackslash
übersetzt u.a. \xnn, \unnnn
und \Unnnnnnnn
(n sind hexadezimale Ziffern) in Unicode-Zeichen. Steht diese Option in einem Compiler nicht zur Verfügung, so gibt es auch noch andere Möglichkeiten Unicode-Zeichen zu verarbeiten. Details dazu siehe unter obenstehenden Link.
Das intrinsische Modul iso_c_binding
Bearbeiten
Das iso_c_binding
-Modul liefert die Konstanten und Unterprogramme, die für die Einbindung von C-Bibliotheken in Fortran-Programme erforderlich sind. Näheres dazu findet sich im Kapitel Fortran 2003 und C.
Die intrinsischen IEEE-Module
BearbeitenDie bereits aus dem dem TR 15580 : 1998 (floating-point exception handling) bekannten Module
ieee_exceptions
ieee_arithmetic
ieee_features
wurden in Fortran 2003 in Form von intrinsischen Modulen aufgenommen. Diese Module decken den IEEE 754-1985-Standard (auch IEC 559:1989) ab.
Wovon handelt der IEEE 754-1985-Standard?
BearbeitenIm Bereich der Gleitkommazahlen (real
, float
, ...) herrschte bis in die 1980er-Jahre Anarchie. Es gab keine verbindlichen Regeln wie Gleitkommazahlen repräsentiert werden, wie gerundet wird, wie Under- und Overflows gehandhabt werden, wie mit Unendlich und NaN verfahren wird, etc. Das führte dazu, dass das gleiche Computerprogramm auf unterschiedlichen Rechnerarchitekturen und mit verschiedenen Compilern unterschiedliche Resultate liefern konnte. Um diesem Manko zu begegnen wurde in den frühen 1980er-Jahren eine Standardisierung angestrebt. Resultat war die Verabschiedung des IEEE 754-1985-Standards (IEEE Standard for Binary Floating-Point Arithmetic for microprocessor systems).
Dieser Standard regelt im Wesentlichen
- die Repräsentation von Gleitkommazahlen:
Darstellung:
s | ... | Vorzeichen |
m | ... | Mantisse |
b | ... | Basis (2 für normalisierte Zahlen) |
e | ... | Exponent |
Zahlenformate:
single | ... | 4 Bytes |
double | ... | 8 Bytes |
double-extended | ... | ≥10 Bytes, optional |
- die Darstellung normalisierter und denormalisierter Zahlen:
- Normalisierte Zahlen: Gleitkommazahlen#Normalisierung
- Denormalisierte Zahlen: Bereich zwischen der kleinsten darstellbaren normalisierten Zahl und Null (Exponent hat einen reservierten Wert, führende Bit der Mantisse ist 0)
- NaN (Not a Number), ,
- Rundungen (zur nächstgelegenen darstellbaren Zahl, in Richtung Null, in Richtung oder in Richtung )
- das Verhalten verschiedener Operationen (Grundrechenarten, Wurzelberechnung, Konvertierung Gleitkommazahl → Ganzzahl, Binär-Dezimal-Konvertierung, Vergleiche mit Nan und , etc.)
- Exception-Handling (Overflow, Underflow, Division by Zero, Inexact, Invalid)
Weiterführende Weblinks:
- IEEE 754
- Kahan, W.: Why do we need a floating-point arithmetic standard?, UC Berkeley, 1981, [1]
- Kahan, W.: Lecture Notes on the Status of IEEE Standard 754 for Binary Floating-Point Arithmetic, UC Berkeley, 1996, [2]
Implementierung in Fortran 2003
BearbeitenWie bereits erwähnt, besitzt Fortran 2003 intrinsische Module, mit denen der Zugriff auf bestimmte IEEE-Eigenschaften erfolgen kann. Dazu stehen eine Reihe von Funktionen, Subroutinen, Verbundtypen und Konstanten zur Verfügung. Merkmal ist, dass diese immer mit dem Präfix ieee
beginnen.
ieee_arithmetic
Bearbeiten
Das aus Programmiersicht umfangreichste Modul ist sicherlich ieee_arithmetic
. Dieses enthält zahlreiche Funktionen, Subroutinen und Konstanten.
Abfragefunktionen für die Unterstützung bestimmter IEEE-Elemente, z.B.:
l = ieee_support_datatype( [x] ) |
Prüft ob die IEEE-Arithmetik für einen speziellen real -Datentyps, charakterisiert durch x (Zahl oder Feld), unterstützt wird. Wird kein Argument angegeben, so wird geprüft, ob die IEEE-Arithmetik für alle real -Datentypen unterstützt wird.
|
l = ieee_support_nan( [x] ) |
Prüft, ob NaN-Werte unterstützt werden |
l = ieee_support_rounding( round_value, [x] ) |
Prüft, ob ein bestimmter IEEE-Rundungsmodus unterstützt wird. Mögliche Rundungsmodi sind:
|
Elementare Funktionen, z.B.:
l = ieee_is_finite( x ) |
Prüft, ob der Wert x endlich ist
|
r = ieee_next_after( x, y ) |
Liefert die nächste darstellbare Zahl von x in Richtung y
|
r = ieee_rint( x ) |
Rundet gemäß eingestelltem Rundungsmodus zu einer Ganzzahl und liefert diese Zahl mit dem Datentyp von x zurück.
|
Die Kind-Funktion:
r = ieee_selected_real_kind( [p, r] ) |
Liefert einen kind-Wert |
Nichtelementare Subroutinen, z.B.:
ieee_get_underflow_mode( gradual ) |
Liefert den aktuellen Underflow-Modus |
ieee_set_rounding_mode( round_value ) |
Setzt den IEEE-Rundungsmodus, mögliche Werte für round_value
|
ieee_exceptions
Bearbeiten
Das ieee_exceptions
-Modul enthält zwei Funktionen, mit denen abgefragt werden kann, welche Exceptions unterstützt werden bzw. inwieweit IEEE-Halting unterstützt wird:
l = ieee_support_flag( flag, [x] ) l = ieee_support_halting( flag )
Mögliche Flags sind
ieee_invalid
ieee_overflow
ieee_divide_by_zero
ieee_underflow
ieee_inexact
Des Weiteren sind in diesem Modul einige Subroutinen zum Setzen bzw. Abfragen diverser Flags enthalten:
ieee_get_status( status_value ) ieee_set_flag( flag, flag_value ) ieee_set_halting_mode( flag, halting ) ieee_set_status( status_value )
Bei Einbindung des ieee_arithmetic
-Moduls ist auch automatisch Zugriff auf die public
-Elemente des Moduls ieee_exceptions
gegeben.
ieee_features
Bearbeiten
Das ieee_features
-Modul liefert einige benannte Konstanten, z.B. ieee_datatype
, ieee_inf
, ieee_sqrt
.
Beispiel: Rundungsmodus
BearbeitenIEEE-Subroutinen:
ieee_get_rounding_mode( val ) ieee_set_rounding_mode( flag )
Mögliche Wert für flag
sind:
|
... | default, Rundung zur nächstgelegenen Zahl (wenn das nicht eindeutig möglich ist, dann Rundung zur nächstgelegenen geraden Zahl) |
|
... | Rundung in Richtung 0 |
|
... | Rundung Richtung |
|
... | Rundung Richtung |
Fortran 2003 (oder neuer)-Code |
program bsp use, intrinsic :: ieee_arithmetic implicit none real, dimension(6) :: a = (/ -1.5, -0.5, 0.5, 1.5, 2.5, 3.5 /) ! Standard-Fortran-Rundungsfunktion write( *, * ) anint( a ) ! IEEE-Rundungsfunktion (default) write( *, * ) ieee_rint( a ) ! IEEE-Rundungsfunktion mit Flag ieee_round_type = ieee_nearest call ieee_set_rounding_mode( ieee_nearest ) write( *, * ) ieee_rint( a ) ! IEEE-Rundungsfunktion mit Flag ieee_round_type = ieee_to_zero call ieee_set_rounding_mode( ieee_to_zero ) write( *, * ) ieee_rint( a ) ! IEEE-Rundungsfunktion mit Flag ieee_round_type = ieee_down call ieee_set_rounding_mode( ieee_down ) write( *, * ) ieee_rint( a ) ! IEEE-Rundungsfunktion mit Flag ieee_round_type = ieee_up call ieee_set_rounding_mode( ieee_up ) write( *, * ) ieee_rint( a ) end program bsp |
Ausgabe:
Standard-Fortran | IEEE-Default | ieee_nearest | ieee_to_zero | ieee_down | ieee_up |
---|---|---|---|---|---|
-2.0 -1.0 1.0 2.0 3.0 4.0 |
-2.0 0.0 0.0 2.0 2.0 4.0 |
-2.0 0.0 0.0 2.0 2.0 4.0 |
-1.0 0.0 0.0 1.0 2.0 3.0 |
-2.0 -1.0 0.0 1.0 2.0 3.0 |
-1.0 0.0 1.0 2.0 3.0 4.0 |
Beispiel: Halting-Modus
BearbeitenDieser Modus bestimmt, ob nach einer Exception das Programm angehalten oder fortgesetzt wird. Die in diesem Beispiel eingesetzten IEEE-Unterprogramme sind:
ieee_support_halting( flag )
... prüft, ob auf dem System das IEEE-Halting für das angegebenen Flag überhaupt unterstützt wird (Rückgabewert:.true.
). Mögliche Flags:ieee_invalid
ieee_overflow
ieee_divide_by_zero
ieee_underflow
ieee_inexact
ieee_set_halting_mode( flag, mode )
... setzt den Halting-Modus für ein bestimmtes Flag.flag
... wie beiieee_support_halting( flag )
mode
:.true.
... anhalten.false.
... Programm weiter ausführen
Fortran 2003 (oder neuer)-Code |
program main use, intrinsic :: ieee_arithmetic implicit none real :: a, b if( ieee_support_halting( ieee_divide_by_zero ) ) then call ieee_set_halting_mode( ieee_divide_by_zero, .false. ) read( *, * ) a, b write( *, * ) "Resultat: ", a / b write( *, * ) "Programm wird fortgesetzt ..." else write( *, * ) "IEEE-Halting wird nicht unterstuetzt" end if end program main |
Eingabe:
- 10.0 (... für a)
- 0.0 (... für b)
Ausgabe (bei Programmerstellung mit dem Sun-Express-Fortran-Compiler f95):
ieee_set_halting_mode( ieee_divide_by_zero, .false. )
|
ieee_set_halting_mode( ieee_divide_by_zero, .true. )
|
---|---|
Resultat: Inf Programm wird fortgesetzt ... |
Gleitkomma-Ausnahme |
Weitere Beispiele zum Thema "Exceptions and IEEE arithmetic" sind im Fortran 2003-Working Draft J3/04-007 ab Seite 386 enthalten.
<<< zur Fortran-Startseite | |
<< Fortran 2003 | Bibliotheken >> |
< Intrinsische Funktionen und Subroutinen | OOP > |