Entwickler-Ecke

Sonstiges (Delphi) - Wertebereich für exp-Funktionsparameter veränderlich?


hjl - Mo 22.08.16 12:07
Titel: Wertebereich für exp-Funktionsparameter veränderlich?
Hi, dies ist mein erster Beitrag hier.

Zur Zeit befasse ich mich mit einem Problem, das mir sehr seltsam erscheint.
Auf Windows 7 Professional, 64 Bit, programmierie ich in Delphi 10.1 (Berlin).

Es betrifft den möglichen Eingabebereich für die Exponentialfunktion Exp für Zahlen vom Typ Extended.
Die Grenzen für Extended liegen bei 3.4e-4932 bis 1.1e4932 für Zahlen > 0.
Bei der Funktion Ln stellte ich fest, dass dessen Ausgabewerte für die Grenzen bei -11355.125903215 bzw. 11356.4449888264 sind.
In einem kleinen Beispielprogramm kann ich zwischen -11355.125903215 und 11356.4449888264 alles von Exp berechnen lassen.
In dem eigentlichen Programm kommt es jedoch schon bei einem Wert von 1, das also ganz klar im zulässigen Bereich liegt, zu einem Gleitkommaüberlauf,
Exception der Klasse EOverflow.
Die Datentypen sind auch im eigentlichen Programm Extended.
Wie kann das sein?
Oder liegt das Problem vielleicht ganz woanders?
LG
hjl

Moderiert von user profile iconChristian S.: Tags aufgespalten


Martok - Mo 22.08.16 14:12

Der EOverflow kann auch von der FPU-Aktion unmittelbar davor kommen, das kannst du rausfinden wenn du im Assembler-Debugger durchsteppst und die FPU-Flags beoachtest und dort auf das OE-Flag (Overflow Exception) wartest.

Hier jetzt offensichtlich nicht zutreffend, prinzipiell aber: wenn du für Win64 compilierst ist der Wertebereich wirklich kleiner, denn dort ist Extended nicht 80bit, sondern nur 64bit (also Double).


Gammatester - Mo 22.08.16 14:54

user profile iconhjl hat folgendes geschrieben Zum zitierten Posting springen:
In dem eigentlichen Programm kommt es jedoch schon bei einem Wert von 1, das also ganz klar im zulässigen Bereich liegt, zu einem Gleitkommaüberlauf, Exception der Klasse EOverflow.

Willst Du damit sagen. daß exp(1) diese Exception erzeugt? Das wäre sehr merkwürdig, sollte aber leicht zu testen sein. Zeig einfach mal etwas (mehr) von Deinem Programm.


hjl - Mo 22.08.16 19:58

@Gammatester:

Die Sache mit dem Gleitkommaüberlauf bei exp(1) hat sich inzwischen erledigt.
Es gab einen Fehler im Programm, das aus mehreren Units besteht, in Form einer versehentlichen Doppeldeklaration einer globalen Variablen.
In einen anderen Fall tritt aber noch ein Gleitkommaüberlauf bei exp(900.xxx) auf, der im Beispielprogramm wiederum auch kein Problem darstellt.
Vermutlich gibt es noch andere Fehler.


@Martok:

Das ist eine sehr interessante Anmerkung, und ich bin inzwischen auf der Embarcadero-Webseite fündig geworden:
http://docwiki.embarcadero.com/RADStudio/Berlin/de/Interne_Datenformate_(Delphi)
Es ist in der Tat so, dass der Programmcode zu Gunsten größerer Arbeitsspeichernutzungsmöglichkeit für Win64Bit compiliert ist,
nachdem es für die mit Delphi7 compilierte 32Bit-Version zu knapp geworden war.
Vielen Dank für diesen Hinweis!
Das dürfte das unterschiedliche Verhalten erklären.
In dem Programm kommen die Funktionen Ln und Exp für Formelumsetzungen häufig vor.


Den Status habe ich jetzt mit "Frage beantwortet" gekennzeichnet.
Dennoch bin ich offen für weitere Anmerkungen.
Danke für die Antworten bisher.
hjl


mandras - Mo 22.08.16 20:07

auch wenn geschlossen, siehe einmal unter "setexceptionmask" nach.
da wird u.a. angegeben, ob/wann eine FPU-Exception auftreten kann.

Ich habs mal mit D6 unter Win7/32 probiert.
Standard ist auch bei mir daß der Fehler später gemeldet wird.
Wird jedoch vorher ein setexceptionmask([exoverflow]) ausgeführt,
erfolgt Exception wie eigentlich gedacht beim ersten exp.


hjl - Di 23.08.16 09:46

Im 64Bit-Code ligt der Eingabebereich der Exp-Funktion also bei -744.440071921381 bis 709.726836893228.
Das ist ein großer Unterschied zum 32Bit-Code. Das kleine Beispielprogramm war zuerst im 32Bit-Code programmiert.
Damit sind alle Exceptions-Vorkommnisse klar.

setexceptionmask kenne ich noch nicht, schau ich mir aber mal an, Danke!
LG hjl