Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - "ungültige Gleitkommazahl"
Sylvus - Do 09.04.09 13:45
Titel: "ungültige Gleitkommazahl"
Hay Leute, mein Programm hat bei bestimmten Eingabewerten ein Problem diese zu verarbeiten und bricht mit der Meldung ab: "ungültige Gleitkommazahl"!
Vll wisst ihr ja woran das liegen könnte.
Mein Quellcode:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| PX1 := Points[I, 1]; PX2 := Points[I + 1, 1]; PX3 := Points[I + 2, 1]; PY1 := Points[I, 2]; PY2 := Points[I + 1, 2]; PY3 := Points[I + 2, 2];
c := sqrt((abs(PX1 - PX2) * abs(PX1 - PX2)) + (abs(PY1 - PY2) * abs(PY1 - PY2))); b := sqrt((abs(PX1 - PX3) * abs(PX1 - PX3)) + (abs(PY1 - PY3) * abs(PY1 - PY3))); a := sqrt((abs(PX2 - PX3) * abs(PX2 - PX3)) + (abs(PY2 - PY3) * abs(PY2 - PY3)));
alpha := radtodeg(arccos(((a * a) - (b * b) - (c * c)) / (-2 * b * c))); beta := radtodeg(arccos(((b * b) - (a * a) - (c * c)) / (-2 * a * c))); |
Und der Stack:
Quelltext
1: 2: 3: 4: 5: 6:
| :7c812a7b kernel32.RaiseException + 0x52 :00403cec NotifyNonDelphiException + $1C :7c91378b ntdll.RtlConvertUlongToLargeInteger + 0x46 :7c91eafa ntdll.KiUserExceptionDispatcher + 0xe :00424e98 ArcCos + $20 pruefeW(???) |
Hat jemand von euch ne Idee? Werden die Zahlen einfach zu groß???
Viele Grüße Sylvus
P.S. Also den Fehler Zeigt er bei alpha:=.... an!
Und die letzten Werte für a,b und c sind:
189,50 93,33 282,84
also gerundet... auf zwei Kommastellen!
thepaine91 - Do 09.04.09 13:59
hi an der größe liegt es nicht das wäre eine andere Meldung ( Gleitkommaüberlauf ) ich komm nur grad nicht drauf worau dieser Fehler zurückzuführen war aber ich denk weiter nach :P
Flamefire - Do 09.04.09 13:59
1) code sollte optimiert werden:
die differenz nur einmal berechnen, auch das abs() kann wegfallen ( "-" * "-" = "+" )
und dann ist es nicht sinvoll als (rechenintensiv) die wurzel zu berechen und dann zu quadrieren, aber das nur am rande
zur fehlersuche:
spalte die zeile mit dem fehler mal auf:
Delphi-Quelltext
1:
| alpha := radtodeg(arccos(((a * a) - (b * b) - (c * c)) / (-2 * b * c))); |
zu
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| a2:=a*a; b2:=b*b; c2:=c*c; diff:=a2-b2-c2; divi:=-2*b*c; alpha:=arccos(diff/divi); alphap:=radtodeg(alpha); |
dann siehst du wo der fehler kommt und warum
Delete - Do 09.04.09 14:06
In welcher der 13 Zeilen tritt der Fehler auf?
Was hast du beim Debuggen rausgefunden?
Flamefire - Do 09.04.09 14:08
@luckie: s. sein edit
bei der alpha:= zeile
Sylvus - Do 09.04.09 14:10
hay super schonmal, also ich vereinfacher das grad....mit der wurzel ist quatsch^^
Aber ich bekomm jetzt bei folgendem Code:
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:
| PX1 := Points[I, 1]; PX2 := Points[I + 1, 1]; PX3 := Points[I + 2, 1]; PY1 := Points[I, 2]; PY2 := Points[I + 1, 2]; PY3 := Points[I + 2, 2];
c := sqrt((abs(PX1 - PX2) * abs(PX1 - PX2)) + (abs(PY1 - PY2) * abs(PY1 - PY2))); b := sqrt((abs(PX1 - PX3) * abs(PX1 - PX3)) + (abs(PY1 - PY3) * abs(PY1 - PY3))); a := sqrt((abs(PX2 - PX3) * abs(PX2 - PX3)) + (abs(PY2 - PY3) * abs(PY2 - PY3)));
a2:=a*a; b2:=b*b; c2:=c*c; d1:=(a2) - (b2) - (c2); d2:=(b2) - (a2) - (c2); e1:=(-2 * b * c); e2:=(-2 * a * c); Form1.Listbox4.Items.Add(floattostr(d1)+ ' '+floattostr(e1)); alp:=arccos((d1) / e1); bet:=arccos((d2) / e2);
alpha := radtodeg(alp);
beta := radtodeg(bet); |
Den Fehler bei "alp:=arccos((d1) / e1);" und zwar ist d1 -70224 und e1 ist auch -70224
aber arccos(1) müsste doch gehen oder?
Viele Grüße Sylvus
thepaine91 - Do 09.04.09 14:13
ArcCos berechnet den inversen Cosinus einer bestimmten Zahl.
Unit
Math
Kategorie
Trigonometrie
function ArcCos(const X: Extended): Extended;
Beschreibung
ArcCos gibt den inversen Cosinus von X zurück. Die Werte von X müssen zwischen -1 und 1 liegen. Der Rückgabewert ist ein Bogenmaß im Bereich von [0..Pi].
delfiphan - Do 09.04.09 14:15
Probier's mal mit:
Delphi-Quelltext
1:
| ArcCos(Min(Max(d1/e1, -1), 1)) |
Natürlich solltest du tatsächlich ungültige Zahlen aussortieren und nicht einfach auf den Bereich [-1,1] projizieren.
Sylvus - Do 09.04.09 14:15
lass mich raten zwischen heißt <>1 und <>-1 oder?
Grandios :D Ok dann werd ich da jetzt mal ne Überprüfung einbauen^^
Mal sehen ob es dann klappt, meld mich dann gleich wieder :)
Dankeschön!
thepaine91 - Do 09.04.09 14:20
eher >= -1 & <= 1
Sylvus - Do 09.04.09 14:23
hmm dann dürfte doch aber nicht passieren....
Weil die werden bei mir ja maximal 1 oder minimal -1!
Hatte jetzt folgendes gebaut:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| if (d1/e1<1)and (d1/e1>-1) then alp:=arccos((d1) / e1) else alp:=0;
if (d2/e2<1) and ( d2/e2>-1) then bet:=arccos((d2) / e2) else bet:=0; |
/edit
aber warum darf das nicht 1 und nicht -1 sein?
Und welchen Wert müsste dann alp und bet annehmen? 0?
//edit2
wieder nen Syntaxfehler...ok müsste jetzt so gehen
Grüße
Kha - Do 09.04.09 14:32
Sylvus hat folgendes geschrieben : |
hmm dann dürfte doch aber nicht passieren....
Weil die werden bei mir ja maximal 1 oder minimal -1! |
Genau, lediglich die endliche Genauigkeit von Fließkommazahlen stellt dir hier ein Bein. Also spricht nichts gegen delfiphans Ansatz.
Sylvus - Do 09.04.09 14:40
ok mach ich so :) Also hätte ich als zahlenbereich integer würde es gehen? Joar ich teste mal rum und probier mich aus :D
Vielen Dank an alle Helfen! Ging schnell und super!
Grüße Sylvus
Kha - Do 09.04.09 15:04
Sylvus hat folgendes geschrieben : |
| Also hätte ich als zahlenbereich integer würde es gehen? |
acos mit Integern ist halt relativ langweilig, da es nur drei verschiedene Winkel gäbe ;) .
Sylvus - Do 09.04.09 16:52
schon klar :) war ja theoretisch gedacht^^
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!