Autor Beitrag
Chiflada
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Di 02.03.04 20:57 
Hi,

vielleicht könnt ihr mir dabei helfen:
ich hab ein c programm was ich benötige und ich delphi "übersetzen" will. hat auch eigentlich geklappt, aber das programm stürzt wegen gleitkommaüberlauf ab. in c ist der datentyp double verwendet und ich hab in delphi extended genommen, also eigentlich dürfte es da ja eigentlich keine probleme geben, oder?
gibt es vielleicht eine möglichkeit sich datentypen selbst zu definieren, die größer sind. ich kann die daten auch nicht verändern, weil ich sie in einer hohen genauigkeit brauche.

danke und bis denne,
jana
DeCodeGuru
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1333
Erhaltene Danke: 1

Arch Linux
Eclipse
BeitragVerfasst: Di 02.03.04 21:07 
Nen Double hat doch einen Speicherbedarf von 8 Byte. Ein Extended hat einen von 10 Byte; außerdem hat Extended einen größeren Wertebereich. Eigentlich dürftest du da keine Probleme bekommen. :?

Poste doch mal die entscheidende Routine. Vielleicht liegt ja ein andere Fehler vor.

_________________
Viele Grüße
Jakob
MaxiTB
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 679

Win2000, WinXp, Workbench ;-)
D7 Ent, VS2003 Arch.
BeitragVerfasst: Di 02.03.04 21:45 
::Chiflada

Zu glauben, long double hat unter MS C++ 80 Bit ist ein Irrglaube ... siehe MSDN: long double = double = 64 Bit !

MS war scheinbar nie in der Lage oder zu faul einen long double zu implementieren ;-) .

Ach ja ... und zum Thema Datentypen C++:

long double 80 Bit
double 64 Bit
float 32 Bit

Also dürftest du kein Problem mit double bekommen - ich denke, daß liegt da wo ganz anders (besonders bei einem Absturz).

_________________
Euer Mäxchen
Wer früher stirbt, ist länger tot.
Chiflada Threadstarter
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Di 02.03.04 22:19 
jut, das dachte ich mir dann auch daß extended ja dann eigentlich mehr hat, aber wie gesagt ich krieg diese fehlermeldung.
das programm ist zur berechnung der feigenbaumkonstante und das c programm hab ich von tpb.physik.rwth-aach.../Feigenbaum/bifurk.c.
ich könnte euch meine delphi übersetzung mal mailen, ich glaub um sie hier ins forum zu stellen, ist sie ein bißchen zu lang.
aber danke für die hilfe!
ciao
MaxiTB
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 679

Win2000, WinXp, Workbench ;-)
D7 Ent, VS2003 Arch.
BeitragVerfasst: Di 02.03.04 22:24 
Der link funkt nicht bei mir *g*.

Und tu dir keinen Zwang an und poste einfach mal deinen Delphi-Code hier - den C-Code kannst du ja richtig verlinken (falls es Fragen gibt, warum du was gemacht hast).

_________________
Euer Mäxchen
Wer früher stirbt, ist länger tot.
Chiflada Threadstarter
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Di 02.03.04 22:43 
hast recht, geht wohl nicht direkt auf ne c datei, aber probier mal den hier: tpb.physik.rwth-aach...Selke/pac/projekt-3/

hier folgt dann die unit zu meinem programm, aber wie gesagt, ist nur abgeschrieben, und hab ich selbst bisher auch noch nicht so ganz verstanden.

ciao, jana


ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
unit FeigKUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TFormFeigK = class(TForm)
    ButtonBerechnen: TButton;
    EditPunkt1: TEdit;
    Editpunkt2: TEdit;
    EditPunkt3: TEdit;
    EditPunkt4: TEdit;
    procedure ButtonBerechnenClick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  FormFeigK: TFormFeigK;

implementation

{$R *.dfm}

const epsilon = 1e-6;
      min_iter = 100000;
      max_fix = 32;

function f(r,x : extended) : extended;
begin
        f := r * x * (1.0 - x);
end;

function count_fix(r : extended) : integer;
var x, xf : extended;
    i, i2 : integer;
begin
        x := 0.5;
        for i := 0 to min_iter do
        begin
        x:=f(r,x);
        xf := x;
        for i2 := 0 to max_fix do
                begin
                        x := f(r,x);
                        if (abs(x-xf) < epsilon) then count_fix := i+1;
                end;
        count_fix := max_fix + 1;
        end;
end;

function locate(r1 : extended; nf1 : integer; r2 : extended; nf2 : integer) : extended;
var r : extended;
    nf : integer;
begin
        r := (r1+r2)/2.0;
        if (abs(r1-r2) < epsilon) then locate := r
        else
                nf := count_fix(r);
                if (nf = nf1) then locate := locate(r,nf,r2,nf2)
                else locate := locate(r1, nf1, r, nf);
                end;


function hunt_and_locate(r : extended) : extended;
var nf1, nf2 : integer;
    dr : extended;
begin
        nf1 := count_fix(r);
        dr := 0.1;
        repeat
        dr := dr * 2.0;
        nf2 := count_fix(r+dr);
        until (nf1 <> nf2);
        hunt_and_locate := locate(r, nf1, r+dr, nf2);
end;

procedure TFormFeigK.ButtonBerechnenClick(Sender: TObject);
var n : integer;
    r: array[0..4of extended;
begin
        r[0] := 2.0;
        for n := 1 to 4 do
                begin
                r[n] := hunt_and_locate(r[n-1]+epsilon);
                end;
        EditPunkt1.Text := FloatToStr(r[1]);
        EditPunkt2.Text := FloatToStr(r[2]);
        EditPunkt3.Text := FloatToStr(r[3]);
        EditPunkt4.Text := FloatToStr(r[4]);
end;

end.


Moderiert von user profile iconDeCodeGuru: Delphi-Tags hinzugefügt
MaxiTB
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 679

Win2000, WinXp, Workbench ;-)
D7 Ent, VS2003 Arch.
BeitragVerfasst: Di 02.03.04 22:51 
Kann nicht gehen ...
Du mußt mal auf alle Fälle ein return in ein Result:= Konvertieren !

Aber ansonsten konnte ich beim Durchsehen keinen Fehler erkennen.
Funktionsnamen gibt man nur in VB als Rückgabeparameter an ;-) .

So - und ich werde mich jetzt mal noch nach Hause haun ... da wartet jemand auf seine versprochene Massage.
Wenn noch was sein sollte, ich schau dann morgen wieder rein ... und bin schließlich nicht der einzige hier !

_________________
Euer Mäxchen
Wer früher stirbt, ist länger tot.
Motzi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: Mi 03.03.04 11:05 
MaxiTB hat folgendes geschrieben:
Funktionsnamen gibt man nur in VB als Rückgabeparameter an ;-) .

Geht in Delphi auch.. aber du hast recht, es ist besser man verwendet Result....

_________________
gringo pussy cats - eef i see you i will pull your tail out by eets roots!
MaxiTB
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 679

Win2000, WinXp, Workbench ;-)
D7 Ent, VS2003 Arch.
BeitragVerfasst: Mi 03.03.04 11:32 
::Motzi

Ups - wußte ich nicht ... ansonsten ist mir eigentlich nix aufgefallen ... :oops:

_________________
Euer Mäxchen
Wer früher stirbt, ist länger tot.
Sven
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 314


D6 Ent, K3 Pro (patched)
BeitragVerfasst: Mi 03.03.04 12:31 
Titel: Rekursiv gehts meistens schief
Chiflada hat folgendes geschrieben:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
const epsilon = 1e-6;
      min_iter = 100000;    //<----- Wahnsinn!!
      max_fix = 32;
...

function count_fix(r : extended) : integer;
var x, xf : extended;
    i, i2 : integer;
begin
    x := 0.5;
    for i := 0 to min_iter do  //<--- Eine absolute Monsterschleife
    begin                      //     Das könnte schiefgehen
        x:=f(r,x);
        xf := x;
        for i2 := 0 to max_fix do
        begin
            x := f(r,x);
            if (abs(x-xf) < epsilon) then count_fix := i+1
        end;
        count_fix := max_fix + 1;
    end;
end;

function locate(r1 : extended; nf1 : integer; r2 : extended; nf2 : integer) : extended;
var r : extended;
    nf : integer;
begin
   r := (r1+r2)/2.0;
   if (abs(r1-r2) < epsilon) then locate := r
                             else nf := count_fix(r); 
   if (nf = nf1) then locate := locate(r,nf,r2,nf2)  //<------ Hier wirds rekursiv !!
                 else locate := locate(r1, nf1, r, nf);
end;
...



Also, Du Rufst eine Funktion Rekursiv auf, und in dieser läuft auch noch eine Schleife mit 100.000 Durchläufen.
Na mich wundert es nicht, wenn da ein Überlauf provoziert wird.

Das Problem ist nicht der Datentyp, sondern schlicht und ergreifend das Programm.

Edit: Kommentare korrigiert

_________________
MDK 9.1, Kernel 2.4.21, KDE 3.1 Kylix 3 Pro (patched), nutze aber auch Windows


Zuletzt bearbeitet von Sven am Mi 03.03.04 14:02, insgesamt 2-mal bearbeitet
MaxiTB
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 679

Win2000, WinXp, Workbench ;-)
D7 Ent, VS2003 Arch.
BeitragVerfasst: Mi 03.03.04 13:21 
ausblenden Delphi-Quelltext
1:
if (abs(x-xf) < epsilon) then Result := i+1;					

Tschuldigung, aber wo ist da die erste Rekursion ?

ausblenden Delphi-Quelltext
1:
if (abs(r1-r2) < epsilon) then Result := r else nf := count_fix(r);					

Oder hier ?

In beiden Fällen ruft sich weder die Funktion selber auf noch wir sie über dritte aufgerufen ... :?

Und der Wert erscheint mir für den Algrithmus ganz in Ordnung zu sein ...
Wenns in C keinen overflow bei einem 64Bit float gibt, warum sollte danns Delphi nicht packen.
Da wird wohl der Fehler wo anders sitzen.

_________________
Euer Mäxchen
Wer früher stirbt, ist länger tot.
Sven
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 314


D6 Ent, K3 Pro (patched)
BeitragVerfasst: Mi 03.03.04 13:59 
@MaxiTB:

Ok, beim ersten habe ich mich versehen, und beim zweiten ist mein Kommentar ein Zeile zuweit oben gelandet.

Ein Schleife von 100.000 Ducrhläufen ist schon sehr massiv bei Berechnungen,

und eine Rekursion ist in der Funktion Locate vorhanden, und somit ein Risiko.

Wenn Du schon die Erbsen in der Suppe zählst, dann überseh bitte nicht das wesentliche.

Es gibt einen Überlauf und der wird mit größter Wahrscheinlichkeit in der sehr großen Schleife, oder beim Rekursiven Aufruf, verursacht

Ein Hinweis in welcher Zeile der Fehler auftritt, wäre natürlich hilfreich gewesen.

Und falls Du den Code mal verfolgst, wirst Du feststellen, da in der rekursiven Funktion Locate die Funktion mit der Monsterschleife aufgerufen wird (werden kann). Da kann eine Zahl durchaus zu groß werden. Selbst für Extended.

Sven

_________________
MDK 9.1, Kernel 2.4.21, KDE 3.1 Kylix 3 Pro (patched), nutze aber auch Windows
Motzi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: Mi 03.03.04 14:40 
Die Schleife ist ja iterativ und löst intern keine Rekursion aus..! Was hat also die Schleife mit dem ganzen zu tun..? Das Problem ist ja auch kein Stack-Überlauf (wie er von einer Rekursion verursacht werden kann), sondern ein Gleitkomma-Überlauf...!

_________________
gringo pussy cats - eef i see you i will pull your tail out by eets roots!
MaxiTB
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 679

Win2000, WinXp, Workbench ;-)
D7 Ent, VS2003 Arch.
BeitragVerfasst: Mi 03.03.04 14:46 
Um zum Thema zurückzukommen:

BUUUUUUUUUUUUUUUUUUUUUUG

Ist mir selber nicht aufgefallen, obwohl die Stelle schon richtig war:

Bitte
ausblenden Quelltext
1:
return x;					

übersetzen in
ausblenden Delphi-Quelltext
1:
begin Result:=x; exit; end;					


Dann klappts auch sicher ohne Überlauf ;-).

Draufgekommen bin ich, weil der Code nämlich sonst keinen Sinn macht und ich mich schon gewundert habe, was das alles eigentlich machen soll *g*. Die einfachsten Dinge übersieht man am leichtesten.

_________________
Euer Mäxchen
Wer früher stirbt, ist länger tot.
Sven
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 314


D6 Ent, K3 Pro (patched)
BeitragVerfasst: Mi 03.03.04 14:49 
@All:

Es ist jetzt nicht böse gemeint, aber habt ihr wirklich Tomaten auf den Augen.

Also:

Locate ruft sich ggf. rekursive auf. Außerdem ruft Locate die Funktion Count_Fix auf. In Count_Fix existiert eine Schleife von 32*100.000 Durchläufen.

Wenn also bei den vielen Multiplikation, Additionen usw. der Zahlenbereich von Extended nicht mehr ausreicht, dann gibt es halt einen na....richtig, Gleitkommaüberlauf.

Ich habe nie behauptet, das die Rekursion an sich eine Exception auslöst.

Nun alles klar?

P.S.: Ich habe auch eine weile gebraucht, bis ich darauf gestoßen bin. :D

_________________
MDK 9.1, Kernel 2.4.21, KDE 3.1 Kylix 3 Pro (patched), nutze aber auch Windows
Brainiac
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mi 03.03.04 14:52 
Nebenbei zur Selbstdefinition von Fließkommazahlen:
Die genannten drei Größen sind schon fest in der FPU integriert, also mit selber definieren ist da nix.
MaxiTB
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 679

Win2000, WinXp, Workbench ;-)
D7 Ent, VS2003 Arch.
BeitragVerfasst: Mi 03.03.04 14:54 
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
unit FeigKUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TFormFeigK = class(TForm)
    ButtonBerechnen: TButton;
    EditPunkt1: TEdit;
    Editpunkt2: TEdit;
    EditPunkt3: TEdit;
    EditPunkt4: TEdit;
    procedure ButtonBerechnenClick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  FormFeigK: TFormFeigK;

implementation

{$R *.dfm}

const epsilon = 1e-6;
      min_iter = 100000;
      max_fix = 32;

function f(r,x : extended) : extended;
begin
 f := r * x * (1.0 - x);
end;

function count_fix(r : extended) : integer;
var
 x, xf : extended;
 i, i2 : integer;
begin
 x := 0.5;
 for i := 0 to min_iter do
 begin
   x:=f(r,x);
   xf := x;
   for i2 := 0 to max_fix do
   begin
    x := f(r,x);
    if (abs(x-xf) < epsilon) then begin Result := i+1; exit; end;
   end;
  end;
  Result := max_fix + 1;
end;

function locate(r1 : extended; nf1 : integer; r2 : extended; nf2 : integer) : extended;
var 
 r : extended;
 nf : integer;
begin
 r := (r1+r2)/2.0;
 if (abs(r1-r2) < epsilon) then begin Result := r; exit; 
 nf := count_fix(r);
 if (nf = nf1) then 
  Result := locate(r,nf,r2,nf2)
 else
  Result := locate(r1, nf1, r, nf);
end;

function hunt_and_locate(r : extended) : extended;
var 
 nf1, nf2 : integer;
 dr : extended;
begin
 nf1 := count_fix(r);
 dr := 0.1;
 repeat
  dr := dr * 2.0;
  nf2 := count_fix(r+dr);
 until (nf1 <> nf2);
 Result := locate(r, nf1, r+dr, nf2);
end;

procedure TFormFeigK.ButtonBerechnenClick(Sender: TObject);
var 
 n : integer;
 r: array[0..4of extended;
begin
        r[0] := 2.0;
        for n := 1 to 4 do
                begin
                r[n] := hunt_and_locate(r[n-1]+epsilon);
                end;
        EditPunkt1.Text := FloatToStr(r[1]);
        EditPunkt2.Text := FloatToStr(r[2]);
        EditPunkt3.Text := FloatToStr(r[3]);
        EditPunkt4.Text := FloatToStr(r[4]);
end;

end.


So in etwa müßte es stimmen, wenn ich mich nicht vertippselt habe ...

Zitat:
Nebenbei zur Selbstdefinition von Fließkommazahlen:
Die genannten drei Größen sind schon fest in der FPU integriert, also mit selber definieren ist da nix.


Was hat die FPU mit der ANSI-C Standardisierung zu tun ?
Wenn die FPU keine 80Bit floats supported, dann muß eben der Compiler native code erzeugen (emulieren). Hat BC ja damals auch gemacht,

_________________
Euer Mäxchen
Wer früher stirbt, ist länger tot.
Brainiac
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mi 03.03.04 19:53 
Also von einer 86er FPU die keine 80Bit Fließkommazahlen unterstützt hab ich jetzt persönlich noch nie gehört.
Alle heutigen FPUs unterstützen die drei Formate dword (Single) qword (Double) und tbyte (Extended) und deshalb haben auch alle modernen Programmiersprachen genau diese drei Größen implementiert.
Natürlich kann man theoretisch auch emulieren, um noch größere Zahlen zu bekommen, aber mit Performance is dann eben nich mehr so toll.