Autor |
Beitrag |
Chiflada
Hält's aus hier
Beiträge: 3
|
Verfasst: 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
      
Beiträge: 1333
Erhaltene Danke: 1
Arch Linux
Eclipse
|
Verfasst: 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
      
Beiträge: 679
Win2000, WinXp, Workbench ;-)
D7 Ent, VS2003 Arch.
|
Verfasst: 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 
Hält's aus hier
Beiträge: 3
|
Verfasst: 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
      
Beiträge: 679
Win2000, WinXp, Workbench ;-)
D7 Ent, VS2003 Arch.
|
Verfasst: 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 
Hält's aus hier
Beiträge: 3
|
Verfasst: 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
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 public 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..4] of 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 DeCodeGuru: Delphi-Tags hinzugefügt
|
|
MaxiTB
      
Beiträge: 679
Win2000, WinXp, Workbench ;-)
D7 Ent, VS2003 Arch.
|
Verfasst: 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
      
Beiträge: 2931
XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
|
Verfasst: 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
      
Beiträge: 679
Win2000, WinXp, Workbench ;-)
D7 Ent, VS2003 Arch.
|
Verfasst: Mi 03.03.04 11:32
::Motzi
Ups - wußte ich nicht ... ansonsten ist mir eigentlich nix aufgefallen ... 
_________________ Euer Mäxchen
Wer früher stirbt, ist länger tot.
|
|
Sven
      
Beiträge: 314
D6 Ent, K3 Pro (patched)
|
Verfasst: Mi 03.03.04 12:31
Titel: Rekursiv gehts meistens schief
Chiflada hat folgendes geschrieben: |
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; 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 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; ... |
|
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
      
Beiträge: 679
Win2000, WinXp, Workbench ;-)
D7 Ent, VS2003 Arch.
|
Verfasst: Mi 03.03.04 13:21
Delphi-Quelltext 1:
| if (abs(x-xf) < epsilon) then Result := i+1; |
Tschuldigung, aber wo ist da die erste Rekursion ?
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
      
Beiträge: 314
D6 Ent, K3 Pro (patched)
|
Verfasst: 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
      
Beiträge: 2931
XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
|
Verfasst: 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
      
Beiträge: 679
Win2000, WinXp, Workbench ;-)
D7 Ent, VS2003 Arch.
|
Verfasst: Mi 03.03.04 14:46
Um zum Thema zurückzukommen:
BUUUUUUUUUUUUUUUUUUUUUUG
Ist mir selber nicht aufgefallen, obwohl die Stelle schon richtig war:
Bitte
Quelltext
übersetzen in
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
      
Beiträge: 314
D6 Ent, K3 Pro (patched)
|
Verfasst: 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. 
_________________ MDK 9.1, Kernel 2.4.21, KDE 3.1 Kylix 3 Pro (patched), nutze aber auch Windows
|
|
Brainiac
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: 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
      
Beiträge: 679
Win2000, WinXp, Workbench ;-)
D7 Ent, VS2003 Arch.
|
Verfasst: Mi 03.03.04 14:54
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 public 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..4] of 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
|
Verfasst: 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.
|
|
|