[ < ] [ 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.
LaTex - Code

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, \[b^-1 \le prod_mantisse < 1.\] , 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 ] [ > ]