Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Problem: 'ungültige Gleitkommaoperation' (https://www.delphipraxis.net/166937-problem-ungueltige-gleitkommaoperation.html)

C0M3T 6. Mär 2012 16:50

Problem: 'ungültige Gleitkommaoperation'
 
Hallo liebe Community,

Dies ist mein erster Post hier, also lasst bitte Nachsicht walten :).
Ich bin leider noch ein ziemlicher Anfänger bei Delphi und stehe nun vor
meinem ersten "schier unlösbaren Problem".
Und zwar bin ich gerade dabei einen simplen Gleichungslöser für quadratische
Gleichungen der allgemeinen Form 0=ax²+bx+c zu basteln (a ungleich 0). Dabei soll mir
das Programm die Lösungsformel für quadr. Gleichungen ( (-p/2)+-Wurzel((p/2)²-q) )
benutzen und die zwei Ergebnisse (x1; x2) in zwei separaten Edit-Feldern ausgeben.
Delphi sagt mir in meinem Quellcode seien keine Fehler enthalten, dennoch erscheint,
wenn ich das Programm starte und Werte eingebe folgende Fehlermeldung:

Exception-Klasse EInvalid OP mit Meldung 'ungültige Gleitkommaoperation'


Hier ist mein Quellcode:

Delphi-Quellcode:
procedure TForm3.Button2Click(Sender: TObject);
 var a,b,c,d,f:real;
begin
 a:=strtofloat(edit1.text);
 b:=strtofloat(edit2.text);
 c:=strtofloat(edit3.text);
 d:=((b/a)/2)+sqrt(((b/a)/2)*((b/a)/2)-c/a);
 Edit4.Text:=FloatToStr(d);
 f:=((b/a)/2)-sqrt(((b/a)/2)*((b/a)/2)-c/a);
 Edit5.Text:=FloatToStr(f);
end;
Woran könnte das liegen?, bzw. welchen Fehler habe ich gemacht?
Ich danke euch schon einmal im Voraus für jede Antwort!

Bummi 6. Mär 2012 17:02

AW: Problem: 'ungültige Gleitkommaoperation'
 
Du solltest überprüfen ob a=0 und gegf. eine Meldung ausgeben ohne zu rechnen
Du solltest vor Wurzeln ziehst prüfen ob die Zahl negativ ist und s.o.

DeddyH 6. Mär 2012 17:04

AW: Problem: 'ungültige Gleitkommaoperation'
 
Hallo und Willkommen in der DP :dp:,

könnte es sein, dass
Zitat:

Delphi-Quellcode:
((b/a)/2)*((b/a)/2)-c/a

einen negativen Wert ergibt? Daraus die Wurzel zu ziehen dürfte nicht funktionieren.

jaenicke 6. Mär 2012 17:13

AW: Problem: 'ungültige Gleitkommaoperation'
 
Zitat:

Zitat von C0M3T (Beitrag 1154811)
dennoch erscheint,
wenn ich das Programm starte und Werte eingebe folgende Fehlermeldung:

Und welche Werte?

Popov 6. Mär 2012 17:13

AW: Problem: 'ungültige Gleitkommaoperation'
 
Es ergibt sich nicht immer ein Fehler, aber z. B. hier

Delphi-Quellcode:
 d:=((8/5)/2)+sqrt(((8/5)/2)*((8/5)/2)-4/5);
Gekürzt

Delphi-Quellcode:
 d:=((8/5)/2)+sqrt(0);
Und das klappt nicht

Delphi-Quellcode:
sqrt(0)

Bummi 6. Mär 2012 17:18

AW: Problem: 'ungültige Gleitkommaoperation'
 
@Popov

sorry, aber Quark SQRT(0) ist kein Problem, SQRT(-0.16) ,korrekt "gekürzt", schon

Popov 6. Mär 2012 17:24

AW: Problem: 'ungültige Gleitkommaoperation'
 
Hast Recht, der Fehler tritt zwei mal auf. Hab die zweite Meldung der ersten Formel zugeordnet.

TiGü 6. Mär 2012 17:51

AW: Problem: 'ungültige Gleitkommaoperation'
 
Warum ziehst nicht einfach eine komplexe Wurzel?

C0M3T 6. Mär 2012 18:19

AW: Problem: 'ungültige Gleitkommaoperation'
 
Vielen Dank, für die zahlreichen Antworten!
Nun, wie kann ich denn dem Progi "sagen", dass es hier bei Negativen Werten,
beispielsweise sqrt(-4), eine Meldung mit
'Nicht lösbar' ausgibt ?
Mit einem "If-Then-Befehl"?

Popov 6. Mär 2012 18:23

AW: Problem: 'ungültige Gleitkommaoperation'
 
Ich tendiere immer dazu alles vorher zu überprüfen, da ich keine Überraschungen mag. Also wie ich es machen würde, wahrscheinlich kompliziert.

Alternativ kannst du die Rechnung in ein Try-Except-End Block packen. Gibt es einen Fehler, wird der Teil in Except ausgeführt.

Aber mal gucken was die anderen vorschlagen.

DeddyH 6. Mär 2012 18:37

AW: Problem: 'ungültige Gleitkommaoperation'
 
Ich würde ja noch 2 weitere Variablen einführen, nennen wir sie g und h, um bei der merkwürdigen Benennung zu bleiben. Das spart Wiederholungen und somit Berechnungen ein und lässt sich im Vorfeld leichter überprüfen.
Delphi-Quellcode:
var
  a, b, c, d, f, g, h: real;
begin
  a := strtofloat(edit1.text);
  b := strtofloat(edit2.text);
  c := strtofloat(edit3.text);
  g := b / a / 2;
  h := sqr(g) - c / a;
  if h < 0 then
    ShowMessage('Nicht lösbar')
  else
    begin
      d := g + sqrt(h);
      f := g - sqrt(h);
      Edit4.text := FloatToStr(d);
      Edit5.text := FloatToStr(f);
    end;
end;

himitsu 6. Mär 2012 18:44

AW: Problem: 'ungültige Gleitkommaoperation'
 
Zitat:

ob a=0
Ergibt einen Division-Durch-0-Fehler.

EDivByZero bei Integer-DIV
EZeroDivide bei Fließkomma-/

Popov 6. Mär 2012 18:50

AW: Problem: 'ungültige Gleitkommaoperation'
 
Zitat:

Zitat von Popov (Beitrag 1154842)
Alternativ kannst du die Rechnung in ein Try-Except-End Block packen. Gibt es einen Fehler, wird der Teil in Except ausgeführt.

Noch ein Nachtrag: soweit du es nicht irgendwo in der IDE abgeschaltet hast, bekommst du immer noch eine hässliche Fehlermeldung. Führst du später die Exe Anwendung direkt aus, kommt die Meldung evtl. nicht, d. h. du mußt selbst für eine Fehlermeldung sorgen.

C0M3T 6. Mär 2012 19:33

AW: Problem: 'ungültige Gleitkommaoperation'
 
Also DaddyH 's Quellcode kurz angepasst und ausprobiert.
Funktioniert nun wunderbar!
Vielen Dank an euch alle, für die schnelle Hilfe!

Delphi-Quellcode:
 var a,b,c,d,f,g,h:real;
begin
 a:=strtofloat(edit1.text);
 b:=strtofloat(edit2.text);
 c:=strtofloat(edit3.text);
 g:= b/a/2;
 h:= g*g-c/a;
 if h<0 then
 ShowMessage('Nicht Lösbar (Wurzel 0)')
 else
  begin
    d:= -g+sqrt(h);
    f:= -g-sqrt(h);
    Edit4.Text:=FloattoStr(d);
    Edit5.Text:=Floattostr(f);
  end;

himitsu 6. Mär 2012 22:28

AW: Problem: 'ungültige Gleitkommaoperation'
 
Zitat:

Zitat von C0M3T (Beitrag 1154857)
Delphi-Quellcode:
if h<0 then

kleiner Null
Zitat:

Zitat von C0M3T (Beitrag 1154857)
Delphi-Quellcode:
ShowMessage('Nicht Lösbar (Wurzel 0)')

gleich Null

:?:

Bummi 6. Mär 2012 22:32

AW: Problem: 'ungültige Gleitkommaoperation'
 
@himitsu
[OT]
bei dem vielen SQL den ich um die Ohren habe tut mir Null=0 weh :wink:
[/OT]

C0M3T 7. Mär 2012 06:25

AW: Problem: 'ungültige Gleitkommaoperation'
 
Habe ich schon angepasst 'Error: Wuzel(-x)'

Popov 7. Mär 2012 07:55

AW: Problem: 'ungültige Gleitkommaoperation'
 
Nur mal mein Senf zu den Bemühungen der letzten Stunden. Irgendwo oben habe ich geschrieben, dass ich von der Einstellung her keine Überraschungen mag, was bedeutet, dass ich zuerst prüfe ob eine Text-Datei vorhanden ist und welche Größe sie hat, bevor ich sie dann ich einem Try-Except Block öffne. Ich hab mal bei einigen meiner Projekte eine Überprüfung gemacht und festgestellt, dass fast ein drittel des Programms aus Überprüfungen besteht. Nun zu dem hier:
Delphi-Quellcode:
 var a,b,c,d,f,g,h:real;
begin
 a:=strtofloat(edit1.text);
 b:=strtofloat(edit2.text);
 c:=strtofloat(edit3.text);
 g:= b/a/2;
 h:= g*g-c/a;
 if h<0 then
 ShowMessage('Nicht Lösbar (Wurzel 0)')
 else
  begin
    d:= -g+sqrt(h);
    f:= -g-sqrt(h);
    Edit4.Text:=FloattoStr(d);
    Edit5.Text:=Floattostr(f);
  end;
Selbst ich mit meinem übertriebenem Kontrollsinn würde irgendwann es gut sein lassen. Eine Formel ist nun mal eine Formel. Eine vorherigen Überprüfung macht nur dann einen Sinn, wenn man eingreifen kann. Wenn ich a/b nehmen, kann ich vorher prüfen ob b gleich 0 ist. Aber was bringt mir das? Nichts. Ich kann die Fehlermeldung abfangen, vielleicht kann ich dem Nutzer auch sagen, dass b gleich 0 ist, wenn er b direkt eingeben kann, aber welchen Sinn macht es bei a/(b-c) vorher zu überprüfen ob b - c = 0 ergibt? Auf was ich hinaus will ist: irgendwann sollte man eine Kosten/Nutzen Rechnung machen. Und hier wäre die Frage: welchen Nutzen hat es eine Formel in seine Bestandteile zu zerlegen? Hat er Einfluss auf h wenn es kleiner 0 ist? Macht er eine 1 draus? Nein, er sagt nur, dass die Formel nicht funktioniert. Und das sagt ihm das System auch. Es hat also keinen Nutzen die Formel zu zerfleischen. Man sollte es irgendwann gut sein lassen. Aber das ist nur mein Senf.

Entweder man ist ein Kontrollfreak und überprüft vorher jeden Teil der Formel, was aber nur Sinn macht wenn man es beeinflussen kann, was hier nicht der Fall ist, oder mal läßt die Formel Formel sein.

Irgendwann sollte mal lernen mit der Fehlermeldung des Systems zu leben.
Delphi-Quellcode:
 var a,b,c,d,f:real;
begin
 a:=strtofloat(edit1.text);
 b:=strtofloat(edit2.text);
 c:=strtofloat(edit3.text);
 try
   d:=((b/a)/2)+sqrt(((b/a)/2)*((b/a)/2)-c/a);
   Edit4.Text:=FloatToStr(d);
 except
   Edit4.Text:='Fehler in der Berechnung 1';
 end;
 try
   f:=((b/a)/2)-sqrt(((b/a)/2)*((b/a)/2)-c/a);
   Edit5.Text:=FloatToStr(f);
 except
   Edit5.Text:='Fehler in der Berechnung 2';
   //...
 end;
end;
Nur mal als Info an C0M3T, eine Fehlermeldung kommt hier nur in der IDE. Beim fertigen Programm sieht man nur die Meldung in den Editfeldern.

DeddyH 7. Mär 2012 08:00

AW: Problem: 'ungültige Gleitkommaoperation'
 
Mal abgesehen davon, dass Du somit das DRY wieder im Code hast, müsstest Du dann aber auch wieder die Exception analysieren. Ich kann Dir aus Erfahrung sagen, dass nichts nerviger ist, als Fehlermeldungen der Art (Originalzitat):
Zitat:

Es ist ein Anwendungsfehler aufgetreten (EAccessViolation)

Popov 7. Mär 2012 08:34

AW: Problem: 'ungültige Gleitkommaoperation'
 
Ich hab zuerst die Fehlermeldung analysiert, hab sie dann wieder entfernt (Teile davon habe ich vergessen, siehe //... im zweiten Except Block), da ich mir überlegt habe welchen Nutzen es bringt zu wissen welcher Fehler vorkam. Dass ein Fehler in der Berechnung vorkommt steht im Editfeld.

Jetzt bitte nicht böse sein, aber was sagt dir die Meldung
Delphi-Quellcode:
'Nicht Lösbar (Wurzel 0)'
, wenn du fünf Editfelder und ein Button auf dem Formular hast? Du fragst dich wahrscheinlich: was für eine Wurzel? Denn von einer Wurzel sehe ich auf dem Formular nichts. Für mich ist das Formular eine Blackbox. Ich gebe drei Zahlen ein und bekomme zwei Ergebnisse, wenn ich Ok klicke. Selbst wenn ich wüßte was für eine Formel dahinter steckt, ich kann es nicht beeinflussen, denn ich hab keinen direkten Einfluss auf h. Soll ich vorher einen Taschenrechner nehmen alles durchrechnen, damit ich fehlerfreie Eingaben machen? Wozu dann bitte das Programm?

Sinn würde es hier machen:
Delphi-Quellcode:
 var a,b,c:real;
begin
 a:=strtofloat(Edit1.text);
 b:=strtofloat(Edit2.text);
 if b = 0 then
 begin
   MessageDlg('Feld 2 enthält 0 (Division durch 0)', mtError, [mbOk], 0);
   Exit;
 end;
 c := a / b;
 Edit3.Text:=FloatToStr(c);
end;
Hier habe ich die Eingaben analysiert und sage dem Anwender wie er den Fehler vermeiden kann. Aber spätestens bei der Formel
Delphi-Quellcode:
c := a / (b - 1)
würde eine Division durch 0 dem Anwender nichts bringen. Die Formel ist Komplex, er hat keinen Einfluß drauf. Also lieber gleich ein allgemeines Error.

Es ist nicht verwerflich eine allgemeine Fehlermeldung auszugeben wenn sie dem Anwender sowieso keinen Sinn ergibt. Und hier macht es keinen Sinn. Die Formel ist zu komplex, er kann sie nicht anpassen.

gammatester 7. Mär 2012 08:43

AW: Problem: 'ungültige Gleitkommaoperation'
 
VIelleicht solltet Ihr bei der ganzen aufgeregten Diskussion nicht vergessen, mal den Code zu testen. Alle vorgestellten Implementation liefern falsche Ergebnisse! Für a = 2, b =-6 und c= 4 sollen die Lösungen angeblich -1 und -2 sein.

C0M3T 7. Mär 2012 08:45

AW: Problem: 'ungültige Gleitkommaoperation'
 
Naja, das Progi ist einzig dazu gedacht, quadratische Gleichungen der Form 0=ax^2+bx+c zu lösen. Demnach muss, bzw. darf man auf die Formel keinen Einfluss haben. Eine Überprüfung der Variablen erscheint mir sinnvoll, mal sehen, ob ich das noch einbaue.

Bummi 7. Mär 2012 09:00

AW: Problem: 'ungültige Gleitkommaoperation'
 
Delphi-Quellcode:
Function SolveQuad(a,b,c:Double;Var x1,x2:Double;ShowErr:Boolean=false):Boolean;
var
 uw:Double;
begin
  Result := false;
  uw := b * b - 4 * a * c;
  try
  if a<>0 then
    begin
      if uw>0 then
        begin
          x1 := (-b + Sqrt(uw)) / (2 * a);
          x2 := (-b - Sqrt(uw)) / (2 * a);
          Result := true;
        end
      else if ShowErr then Messagedlg('Negative Wurzel',mtWarning,[mbok],0);
    end
   else if ShowErr then Messagedlg('Division durch 0',mtWarning,[mbok],0);
  except
    on E:Exception do if ShowErr then Messagedlg(E.Message,mtError,[mbok],0);
  end;

end;


procedure TForm2.Button1Click(Sender: TObject);
var
 a,b,c,d,e:Double;
begin
   if TryStrToFloat(Edit1.Text,a) then
      if TryStrToFloat(Edit2.Text,b) then
           if TryStrToFloat(Edit3.Text,c) then
             if SolveQuad(a,b,c,d,e,true) then
                begin
                  Edit4.Text := FloatToStr(d);
                  Edit5.Text := FloatToStr(e);
                end;
end;

gammatester 7. Mär 2012 09:04

AW: Problem: 'ungültige Gleitkommaoperation'
 
Zitat:

Zitat von C0M3T (Beitrag 1154968)
Naja, das Progi ist einzig dazu gedacht, quadratische Gleichungen der Form 0=ax^2+bx+c zu lösen. Demnach muss, bzw. darf man auf die Formel keinen Einfluss haben.

Häh :?: Was sind denn die Ergebnisse, wenn Du 0 = 2x^2 - 6x + 4 mit Deiner Methode löst? Und wenn Du Deine abgeblichen Lösungen mal einsetzt, was kommt dann raus?

Ihr (Edit: Ausnahme Bummi) benutzt schlicht und einfach die falsche Formel!

TiGü 7. Mär 2012 09:16

AW: Problem: 'ungültige Gleitkommaoperation'
 
Zitat:

Zitat von gammatester (Beitrag 1154978)
Zitat:

Zitat von C0M3T (Beitrag 1154968)
Naja, das Progi ist einzig dazu gedacht, quadratische Gleichungen der Form 0=ax^2+bx+c zu lösen. Demnach muss, bzw. darf man auf die Formel keinen Einfluss haben.

Häh :?: Was sind denn die Ergebnisse, wenn Du 0 = 2x^2 - 6x + 4 mit Deiner Methode löst? Und wenn Du Deine abgeblichen Lösungen mal einsetzt, was kommt dann raus?

Ihr (Edit: Ausnahme Bummi) benutzt schlicht und einfach die falsche Formel!

Bevor jetzt alle anfangen mit Taschenrechner und Tafelwerk zu hantieren:
http://www.wolframalpha.com/input/?i...x^2%2B-6*x%2B4

C0M3T 7. Mär 2012 15:49

AW: Problem: 'ungültige Gleitkommaoperation'
 
@Gammatester:

Also mit meiner Formel kommen die beiden richtigen Ergenisse raus. (1&2)
eingesetzt in die Gleichung ergeben beide 0. So soll es sein.:-D

gammatester 7. Mär 2012 17:18

AW: Problem: 'ungültige Gleitkommaoperation'
 
Sorry! Das ist richtig, beim nochmaligem Überfliegen, sieht es so aus, als wenn ab Popov's Teil 2 in #18 wurde mit b/(2a) +- gearbeitet.


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:57 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz