Fortran: Fortran 2003: Intrinsische Module
Grundlegendes
Module 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
Das iso_fortran_env-Modul enthält einige Fortran-umgebungsspezifische Konstanten.
Beispiel:
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:Vorlage: Pre4
Beispiel (Ausgabe eines Unicode-Zeichens, siehe auch Programming in Modern Fortran - Unicode): Fortran:Vorlage: Pre4
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
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
Die bereits aus dem dem TR 15580 : 1998 (floating-point exception handling) bekannten Module
ieee_exceptionsieee_arithmeticieee_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?
Im 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: Vorlage:W
- 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:
- Vorlage:W
- 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
Wie 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
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
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_invalidieee_overflowieee_divide_by_zeroieee_underflowieee_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
Das ieee_features-Modul liefert einige benannte Konstanten, z.B. ieee_datatype, ieee_inf, ieee_sqrt.
Beispiel: Rundungsmodus
IEEE-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 |
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
Dieser 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_invalidieee_overflowieee_divide_by_zeroieee_underflowieee_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
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.