[ < ]
[ globale Übersicht ]
[ Kapitelübersicht ]
[ Stichwortsuche ]
[ > ]
3.8.6 Fallstudie
Problemstellung bei der Bildung von Produkten:
Bei der Produktbildung (a1 * a2 * a3 ... * an) ist es bei einem großem n möglich, daß bei der schrittweisen
Berechnung die untere oder aber die obere Zahlengrenze überschritten wird, obwohl das Endergebnis in dem vorgegebenen
Zahlenbereich liegt.
Bei einem Computer mit einfach genauer IEC/IEEE-Arithmetik , kann man dies an einem Produkt einer
Folge {ai} von 1000 Faktoren betrachten.
Wenn man nun diese Berechnung anstellt erhält man für das Zwischenergebnis i=326, ein Ergebnis,
daß außerhalb des Zahlenbereiches liegt ( d.h. es ist in unserem Fall ein overflow vorhanden ),
obwohl alle anderen Zwischenergebnisse im Wertebereich liegen.
In Fortran 90 kann mit Hilfe des Gebrauches von vordefinierten Funktionen für die Gleitpunktzahlen diesem
Problem ausgewichen werden.
Produktbildung ohne Überlauf - Version A
Bei diesem Verfahren werden die Zwischenergebnisse von Exponent und Mantisse getrennt gespeichert.
Bei jedem weiteren Schleifendurchlauf wird nun die Mantisse des neuen Faktors mit dem Zwischenprodukt
der Mantissen multipliziert und der Exponent wird mit der Zwischensumme der Exponenten addiert.
SET_EXPONENT setzt nun das Ergebnis - wenn es im Wertebereich liegt - zu einer REAL-Zahl zusammen.
Bei diesem Programm wird der Wertebereich nicht verlassen, da für prod_mantisse,
, gilt.
Beispiel 1
Sourcecode für Variante 1 der überlauffreien Produktbildung
INTEGER :: i, n, prod_exponent
REAL :: prod_mantisse, produkt
REAL, DIMENSION (n) :: faktor
...
prod_mantisse = 1
prod_exponent = EXPONENT (prod_mantisse)
prod_mantisse = FRACTION (prod_mantisse)
DO i = 1, n
prod_exponent = prod_exponent + EXPONENT (faktor(i))
prod_mantisse = prod_mantisse * FRACTION (faktor(i))
prod_exponent = prod_exponent + EXPONENT (prod_mantisse)
prod_mantisse = FRACTION (prod_mantisse)
END DO
PRINT *, "Ergebnis:"
IF ((prod_exponent <= MAXEXPONENT (produkt)) .AND. &
(prod_exponent >=MINEXPONENT (produkt))) THEN
produkt = SET_EXPONENT (prod_mantisse, prod_exponent)
PRINT *, produkt
ELSE
PRINT *, "liegt ausserhalb des Bereichs der Gleitpunkt - Modellzahl!"
END IF
Produktbildung ohne Überlauf - Version B
Bei dieser zweiten Methode , addiert man die Exponenten der Faktoren und multipliziert die Zwischenergebnisse mit
ihren Mantissen, ohne daß man zwischendurch skaliert.
Bei diesem Programm kann sehr leicht die untere Grenze unterschritten werden, da die Variable prod_mantisse immer
wieder verkleinert wird. Hier kann man Abhilfe schaffen, in dem eine Abbruchbedingung mit Hilfe der Funktion TINY
realisiert wird. In unserem Fall wird bei Faktor a209 abgebrochen.
Beispiel 2
Sourcecode für Variante 2 der überlauffreien Produktbildung
INTEGER :: i, n, prod_exponent
REAL :: prod_mantisse, produkt
REAL, DIMENSION (n) :: faktor
...
prod_exponent = 0
prod_mantisse = 1
vollstaendig = .TRUE.
DO i = 1, n
IF ((prod_mantisse * FRACTION (faktor(i))) < TINY (prod_mantisse) Then
PRINT *, "Modellzahlenbereich wird verlassen !"
PRINT *, "Produkt wurde bis Faktor", (i-1), "berechnet."
vollständig = .FALSE.
EXIT
END IF
prod_exponent = prod_exponent + EXPONENT (faktor(i))
prod_mantisse = prod_mantisse * FRACTION (faktor(i))
END DO
IF (vollstaendig) THEN
PRINT *, "Produkt vollstaendig berechnet"
END IF
gesamt_exponent = prod_exponent + EXPONENT (prod_mantisse)
IF ((gesamt_exponent >=MINEXPONENT (prod_mantisse)) .AND. &
(gesamt_exponent<=MAXEXPONENT (prod_mantisse))) THEN
produkt = SET_EXPONENT (prod_mantisse, prod_exponent)
PRINT *, "Ergebnis"
PRINT *, SCALE (prod_mantisse, prod_exponent)
ELSE
PRINT *, "Ergebnis liegt ausserhalb der Modellzahlen !"
END IF
[ < ]
[ globale Übersicht ]
[ Kapitelübersicht ]
[ Stichwortsuche ]
[ > ]