Seltsames Variablenverhalten?!

Hallo C++ Experte,

Ich habe für ein Übungsblatt ein Script geschrieben, das Werte für eine Funktion (einmal nur mit „float“- und einmal nur mit „double“-Variablen) ausrechnet, diese in eine Datei schreibt und den Dateiinhalt anschließend auf dem Bildschirm ausgibt.

Das Script läuft, so wie ich es unten eingefügt habe, absolut problemfrei.

Meine eigentliche Frage:

Woher kommen die Unterschiede zwischen den mit „float“ bzw. „double“ berechneten Ergebnissen?? Die anfänglichen Werte von x0 wie 1 oder 0,1 übersteigen doch keinesfalls den Wertebereich von „float“, so daß Fehler entstehen könnten.

Und welche Ergebnisse („float“ oder „double“) sind die richtigen??

Und warum erfolgt eine andere Ausgabe, wenn ich dh_ende bei der „double“-Berechnung, genau wie bei „float“ =pow(10,-23) setze und dann „while (dh>dh_ende)“ benutze??
Warum wird die gleiche Schleife unterschiedlich oft wiederholt??

Bitte lass das Script einfach mal probelaufen und schau Dir ausgabe.txt an. Dann fällt das Problem sofort auf.

Im Voraus vielen Dank

megaflachs

Das Script:

#include
#include
#include
#include

using namespace std;

float fx0;
double dx0;
char dateiinhalt;

float x01_zeile()
{
ofstream ausgabedatei(„ausgabe.txt“, ios::trunc); // „trunc“ löscht evt. vorhandene Datei

ausgabedatei fh_ende)
{
fx0h = fx0 + fh;

fterm1 = -fx0h * fx0h + 4.0f * fx0h - 2.5f;
fterm2 = -fx0 * fx0 + 4.0f * fx0 - 2.5f;

fergebnis = (fterm1 - fterm2) / fh;
ffehler = (fterm1 - fterm2) / fh - 2.0f;
fbetragfehler = sqrt(ffehler * ffehler);

ausgabedatei =dh_ende)
{
dx0h = dx0 + dh;

dterm1 = -dx0h * dx0h + 4.0 * dx0h - 2.5;
dterm2 = -dx0 * dx0 + 4.0 * dx0 - 2.5;

dergebnis = (dterm1 - dterm2) / dh;
dfehler = (dterm1 - dterm2) / dh - 2.0;
dbetragfehler = sqrt(dfehler * dfehler);

ausgabedatei

Hallo megaflachs ,

Meine eigentliche Frage:

Woher kommen die Unterschiede zwischen den mit „float“ bzw.
„double“ berechneten Ergebnissen?? Die anfänglichen Werte von
x0 wie 1 oder 0,1 übersteigen doch keinesfalls den
Wertebereich von „float“, so daß Fehler entstehen könnten.

Und welche Ergebnisse („float“ oder „double“) sind die
richtigen??

Hier ein Auszug aus dem Visual C++ Handbuch:

Table 3.3 Floating-Point Types

Type Significant digits Number of bytes 
float 6 – 7 4 
double 15 – 16 8 

Floating-point variables are represented by a mantissa, which contains the value of the number, and an exponent, which contains the order of magnitude of the number.

Somit ergibt sich für float:
1.000000 + 1E-8 = 1.000000
und für double liegt die Grenze bei 1e-17
Dies stimmt bei meinem Compiler mit den Resultaten der Tabelle überein.

Bei einem Floating-Point gibt es 2 wichtige Werte für Zahlen:

  1. der Werte-Bereich (Wird durch den Exponent bestimmt)
  2. die Anzahl darstellbarer Ziffern (Wird durch die Mantisse bestimmt)

Hinzu kommen noch evtl. Probleme mit Over-/Underflow bei Zwischenresultaten.
z.B.:
a = (b*c)/d;
Obwohl das Endresultat numerisch innerhalb des Gültigkeitsbereichs liegt kann (b*c) einen Overflow erzeugen und somit liefert das Ganze ein falsches Resultat.

Bei C(++) musst du, im Gegensatz zu z.B. BASIC, selbst überprüfen on es einen Over/Underflow gegeben hat.

MfG Peter(TOO)