PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Gleitkommafehler


Lord Nikon
2003-11-12, 18:42:04
Hi ,
ich habe folgenden Code:

for ( zahler = 0;zahler<255;zahler++)
{
r[zahler]=random(10)/10.0;

g[zahler]=random(10)/10.0;
b[zahler]=random(10)/10.0;
mem->Lines->Add("R:"+AnsiString(r[zahler]));
mem->Lines->Add("G:"+AnsiString(g[zahler]));
mem->Lines->Add("B:"+AnsiString(b[zahler]));
}
// Ausschnitt der Grafik
x1 = -2.0 ;
y1 = -1.6 ;
x2 = 1 ;
y2 = 1.6 ;
depth = 140; // maximal 255 (sonst mehr Zufallsfarben erzeugen!)
dx = (x2 - x1) /2.5 ;
dy = (y2 - y1) / 2.5 ;

for ( y = -2.5 ;y<2.5;y=y+0.1)

for ( x = -2.5;x<2.5;x=x+0.1)
{
px = x1 + x * dx ;
py = y1 + y * dy ;
d = 0 ;
ax = 0 ;
ay = 0 ;
do
{
u = ax * ax - ay * ay + px;
v = 2 * ax * ay + py ;

ax = u ;
ay = v ;
d += 1 ;

glColor3f(r[d],g[d],b[d]);
glBegin(GL_POINT);
glVertex2d(x,y);
glEnd();

}
while ( (ax * ax + ay * ay )> 8 || d == depth);
}


glFlush();
glFinish();


SwapBuffers(wglGetCurrentDC())

Wieso kommt ein Gleitkommaüberlauf nach 8 Durchläufen ?

Gast
2003-11-13, 11:23:03
keiner ne Ahnung ?

Crushinator
2003-11-13, 15:27:42
Wenn Du noch die Variablen-Deklaration und die Funktion "random" posten könntest, wäre es zumind. für mich um einiges leichter den Grund herauszufinden.

Lord Nikon
2003-11-13, 16:06:27
random ist eine methode aus math.h. Sie liefert eine Zufallszahl zurück.
Variablen:


double x, y; // ' Laufvariablen
double x1, y1, x2, y2; // ' Mandelbrot-Ausschnitts-Koordinaten
int depth ; // Berechnungstiefe
int d; // Laufvariable für Tiefe
double dx, dy ; // Schrittweite pro Pixel
double px, py; // aktuelle Weltkoordinate
double u, v; // Berechnungsvariablen
double ax, ay ; // Berechnungsvariablen
double r[255];
double g[255];
double b[255];
int zahler=0;

DocEW@Uni
2003-11-13, 17:05:52
Was genau läuft denn "über"? ?(

Crushinator
2003-11-13, 17:33:40
Hättest ruhig erwähnen können, daß es sich um GCC handelt. ;) Der Überlauf passiert jedenfalls außerhalb der Arithmetik, weil er bei mir nicht auftritt, wenn ich die "mem" und "gl*" Zeilen rausnehme. (hab' gerad nicht die richtigen libs und .h auf der Kiste griffbereit) :ratlos:

Lord Nikon
2003-11-13, 17:58:38
ich verwende kein gcc. Ich vewende den c++ builder 6.0.Ich teste mal ohne die mem und gl Befehle.

EDIT:
Test ohne Mem:
v = 2 * ax * ay + py kriegt er den fehler
EDIT 2:
Test ohne Mem und ohne Gl Befehle
v = 2 * ax * ay + py kriegt der einen fehler

Crushinator
2003-11-13, 19:50:15
Das schreit nach Exxtreme, denn ich habe z.Z. keinen BCB 6.0 und unter GCC (Linux) tat es das ohne Überlauf.

Exxträäääääähhhhmmmmme, huuuuuhuuuuuu, :help: plz. :wink:

Exxtreme
2003-11-13, 20:32:33
Sorry Mädelz, aber von OpenGL-Programmierung habe ich keinen Schimmer. ;(

Zeckiiiiiii!!!!!111

X-D

Crushinator
2003-11-13, 20:59:48
^^ Du kannst aber doch bitte schonmal schauen, ob ein "Hello World" bei dem davor die ganze Geschichte (ohne mem und gl*) ausgeführt wird genau so einen Überlauf erzeugt wie beim Lord. X-D

Crushinator
2003-11-13, 22:28:33
Mein lieber Lord, Du machst ja Sachen. :nono: Also, einmal Debuggen in VC brachte das Ergebnis, daß Du mit Deinem Code tatsächlich an besagter Stelle (v = ...) über den Range des Typs double hinausschiesst, und nach ändern aller relevanten Variablen in long double spätestens dann...

while ( (ax * ax + ay * ay )> 8 || d == depth);

...auch die 80 bits der FPU sprengst.

Die Erklärung, warum es mir weder mit VC++ (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/HTML/_crt__control87.2c_._controlfp.asp) von MS noch mit GCC auffiel ist die, daß beide zuvorgenannten die FP-Exceptions per Default maskieren. Abgesehen davon, daß ich nicht weiß, warum der Code solche Zahlen erzeugen bzw. mit denen rechnen soll, habe ich z.Z. nur die sogenannte Hauptsache-es-geht-erstmal-Lösung™, nämlich mit den anderen Beiden gleichzuziehen:

_control87(MCW_EM, MCW_EM); /* defined in float.h */
...gehört vor die erste Schleife.

zeckensack
2003-11-14, 00:44:49
{
<...>
} while ( (ax * ax + ay * ay )> 8 || d == depth);
Falsche Schleifenbedingung.
Der Code rechnet bei bestimmten Samples unendlich lang, und erzeugt dabei unendlich große Zahlen. Das Abmaskieren der FPU-Exceptions macht daraus einen Hänger.

Vorschlag:{
<...>
} while ( ((ax * ax + ay * ay )<8) && (d<depth));

Das müßte schonmal funzen, ist aber nicht die 'korrekte' Abbruchbedingung für Mandelbrot. Die sieht so aus:{
<...>
} while ( ((ax * ax + ay * ay )<4) && (d<depth));

Xmas
2003-11-14, 01:09:33
LOL, das seh ich jetzt erst dass das ein Mandelbrotrenderer ist... die Variablennamen sind auch etwas unüblich ;)

Die GL-Funktionsaufrufe sollten aber auf jeden Fall woanders hin, glBegin und glEnd sollten komplett außerhalb der for-Schleifen stehen, und glColor und glVertex nicht innerhalb der do-while Schleife.

Lord Nikon
2003-11-14, 13:49:26
Original geschrieben von Xmas
LOL, das seh ich jetzt erst dass das ein Mandelbrotrenderer ist... die Variablennamen sind auch etwas unüblich ;)

Die GL-Funktionsaufrufe sollten aber auf jeden Fall woanders hin, glBegin und glEnd sollten komplett außerhalb der for-Schleifen stehen, und glColor und glVertex nicht innerhalb der do-while Schleife.

Die Variablennamen waren von meinem Lehrer vorgegeben.
@all
thx für die Antworten.Der Gleitkommaüberlauf ist jetzt weg und alles funktioniert wie es soll

=)