Autor Beitrag
JonesAdams
Hält's aus hier
Beiträge: 7



BeitragVerfasst: So 19.04.09 08:58 
Hi zusammen!

Ich wollte eins von diesen Programmen für die Quader berechnung entwickeln, mit dem man durch Angabe von nur drei Werten alle weiteren bekomme.

Ich hab' meine grauen Zellen schon aktiviert und das hier zu Papier gebracht:

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:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
unit QUADERSPECIAL;

interface

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

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit3: TEdit;
    Edit4: TEdit;
    Edit5: TEdit;
    Edit6: TEdit;
    Button1: TButton;
    Memo1: TMemo;
    Edit2: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var a,b,c,d,v,o: real;
begin
if Edit1.Text <> '' then
begin
a:=strtofloat(Edit1.Text);
end;
if Edit2.Text <> '' then
begin
b:=strtofloat(Edit2.Text);
end;
if Edit3.Text <> '' then
begin
c:=strtofloat(Edit3.Text);
end;
if Edit4.Text <> '' then
begin
d:=strtofloat(Edit4.Text);
end;
if Edit5.Text <> '' then
begin
v:=strtofloat(Edit5.Text);
end;
if Edit6.Text <> '' then
begin
o:=strtofloat(Edit6.Text);
end;
repeat
begin
if b=0 then
begin
b:=v/(a*c);
b:=((o/2)-(a*c))/(a+c);
if (a<>0and (c<>0and (d<>0then
begin
b:=sqrt(sqr(d)-sqr(a)-sqr(c));
end;
end
else
if a=0 then
begin
a:=v/(b*c);
a:=((o/2)-(b*c))/(b+c);
if (b<>0and (c<>0and (d<>0then
begin
a:=sqrt(sqr(d)-sqr(b)-sqr(c));
end;
end
else
if c=0 then
begin
c:=v/(b*a);
c:=((o/2)-(b*a))/(b+a);
if (a<>0and (b<>0and (d<>0then
begin
c:=sqrt(sqr(d)-sqr(b)-sqr(a));
end;
end
else
if d=0 then
begin
if (a<>0and (c<>0and (d<>0then
begin
d:=sqrt(sqr(a)+sqr(d)+sqr(c));
end;
end
else
if o=0 then
begin
o:=2*(a*b+a*c+b*c);
end;
if v=0 then
begin
v:=a*b*c;
end;
end;
until (a<>0and (b<>0and (c<>0and (d<>0and (o<>0and (v<>0);
memo1.Visible:= True;
Memo1.Clear;
Memo1.Lines.Add('Seitenlänge a         ' + FloatToStrF(a, fffixed, 10,2));
Memo1.Lines.Add('Seitenlänge b         ' + FloatToStrF(b, fffixed, 10,2));
Memo1.Lines.Add('Seitenlänge c         ' + FloatToStrF(c, fffixed, 10,2));
Memo1.Lines.Add('Diagonale d           ' + FloatToStrF(d, fffixed, 10,2));
Memo1.Lines.Add('Volumen V             ' + FloatToStrF(v, fffixed, 10,2));
Memo1.Lines.Add('Oberfläche O          ' + FloatToStrF(o, fffixed, 10,2));
end;

end.


Leider friert das Programm beim Drücken auf den Button jedes mal ein... wird wohl an der "repeat"-schleife liegen...
Vielleicht habt ihr ja noch ein paar Ideen, die mir helfen können?

Vielen Dank!
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19314
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 19.04.09 09:15 
Hallo und :welcome: im Forum!

Leider kann man bei der Quelltext"formatierung" und den Variablenbezeichnungen rein gar nichts erkennen...

Rück den Quelltext bitte erstmal ein.
Und schreib zumindest dazu was die Variablen für Werte enthalten, wenn du schon keine richtigen Namen für die Variablen und Edits nehmen kannst...

Allgemeiner Tipp: Es gibt auch TryStrToFloat statt den vielen ifs am Anfang, womit du auch falsche Eingaben (keine Zahlen) abfängst.

// EDIT:
Ach ja: bei welchen Werten friert das Programm eigentlich ein, also kommt in eine Endlosschleife?
JonesAdams Threadstarter
Hält's aus hier
Beiträge: 7



BeitragVerfasst: So 19.04.09 09:41 
Hi, vielen Dank für die schnelle Antwort! Und sorry für die Anfängerfehler!
Also, die Variablen:

a (Edit1), b(Edit2) und c(Edit3) sind die Seitenlängen des Quaders;
d(Edit4) ist die Raumdiagonale;
v(Edit5) ist das Volumen
und o(Edit6) die Oberfläche.

Einen Quader könnte man ja vollkommen mit drei der Werte berechnen. Doch egal, welche drei Editfelder (die ursprünglich leer sind), gefüllt werden, das Programm friert ein.

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:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
unit QUADERSPECIAL;

interface

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

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit3: TEdit;
    Edit4: TEdit;
    Edit5: TEdit;
    Edit6: TEdit;
    Button1: TButton;
    Memo1: TMemo;
    Edit2: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var a,b,c,d,v,o: real;
begin
if Edit1.Text <> '' then
 begin
 a:=strtofloat(Edit1.Text);
 end;
if Edit2.Text <> '' then
 begin
 b:=strtofloat(Edit2.Text);
 end;
if Edit3.Text <> '' then
 begin
 c:=strtofloat(Edit3.Text);
 end;
if Edit4.Text <> '' then
 begin
 d:=strtofloat(Edit4.Text);
 end;
if Edit5.Text <> '' then
 begin
 v:=strtofloat(Edit5.Text);
 end;
if Edit6.Text <> '' then
 begin
 o:=strtofloat(Edit6.Text);
 end;

repeat
begin
 if b=0 then
  begin
  b:=v/(a*c);
  b:=((o/2)-(a*c))/(a+c);

   if (a<>0and (c<>0and (d<>0then
    begin
    b:=sqrt(sqr(d)-sqr(a)-sqr(c));
    end;

  end;


 if a=0 then
  begin
  a:=v/(b*c);
  a:=((o/2)-(b*c))/(b+c);

   if (b<>0and (c<>0and (d<>0then
    begin
    a:=sqrt(sqr(d)-sqr(b)-sqr(c));
    end;

  end;


 if c=0 then
  begin
  c:=v/(b*a);
  c:=((o/2)-(b*a))/(b+a);

   if (a<>0and (b<>0and (d<>0then
    begin
    c:=sqrt(sqr(d)-sqr(b)-sqr(a));
    end;

  end;


 if d=0 then
  begin

   if (a<>0and (c<>0and (d<>0then
    begin
    d:=sqrt(sqr(a)+sqr(d)+sqr(c));
    end;

  end;

 if o=0 then
  begin
  o:=2*(a*b+a*c+b*c);
  end;

 if v=0 then
 begin
 v:=a*b*c;
 end;

end;
until (a<>0and (b<>0and (c<>0and (d<>0and (o<>0and (v<>0);
memo1.Visible:= True;
Memo1.Clear;
Memo1.Lines.Add('Seitenlänge a         ' + FloatToStrF(a, fffixed, 10,2));
Memo1.Lines.Add('Seitenlänge b         ' + FloatToStrF(b, fffixed, 10,2));
Memo1.Lines.Add('Seitenlänge c         ' + FloatToStrF(c, fffixed, 10,2));
Memo1.Lines.Add('Diagonale d           ' + FloatToStrF(d, fffixed, 10,2));
Memo1.Lines.Add('Volumen V             ' + FloatToStrF(v, fffixed, 10,2));
Memo1.Lines.Add('Oberfläche O          ' + FloatToStrF(o, fffixed, 10,2));
end;

end.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19314
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 19.04.09 09:51 
Ok, erstens initialisierst du die Variablen nicht, wenn nix in dem entsprechenden Edit ist. Wie wäre es lieber so? ;-)
ausblenden Delphi-Quelltext
1:
  if TryStrToFloat(Edit1.Text, a) and TryStrToFloat(Edit2.Text, b) and ... then					


Dann wirfst du berechnete Werte einfach weg. Wenn die erste Zeile nicht notwendig ist, wofür schreibst du die dann? :gruebel:
ausblenden Delphi-Quelltext
1:
2:
  b:=v/(a*c);
  b:=((o/2)-(a*c))/(a+c);


Und dann das wichtigste:
ausblenden Delphi-Quelltext
1:
2:
3:
 if a=0 then
  begin
  a:=v/(b*c);
Aber woher willst du an der Stelle wissen, dass v, b und c angegeben wurden? :gruebel:

Da musst du schon feststellen welche Werte zur Berechnung zur Verfügung stehen und entsprechend die Berechnung durchführen.

// EDIT:
Crosspost:
www.delphipraxis.net/post1027795.html
JonesAdams Threadstarter
Hält's aus hier
Beiträge: 7



BeitragVerfasst: So 19.04.09 10:03 
Zitat:

Ok, erstens initialisierst du die Variablen nicht, wenn nix in dem entsprechenden Edit ist. Wie wäre es lieber so?
ausblenden Delphi-Quelltext
1:
if TryStrToFloat(Edit1.Text, a) and TryStrToFloat(Edit2.Text, b) and ... then					



Gut, dankeschön!

Zitat:

Dann wirfst du berechnete Werte einfach weg. Wenn die erste Zeile nicht notwendig ist, wofür schreibst du die dann? :gruebel:
ausblenden Delphi-Quelltext
1:
2:
  b:=v/(a*c);
  b:=((o/2)-(a*c))/(a+c);



Das kapier ich ehrlich gesagt nicht.

Zitat:

Und dann das wichtigste:
ausblenden Delphi-Quelltext
1:
2:
3:
 if a=0 then
  begin
  a:=v/(b*c);

Aber woher willst du an der Stelle wissen, dass v, b und c angegeben wurden? :gruebel:


Naja... wenn die Werte vorher nicht in den Edits eingegeben wurden, bleiben sie doch auf "0". Doch irgendeine der Gleichungen wird doch funktionieren und daher das "until a<>0 ..." denn nach ein paar mal Hin-und-her-Gerechne werden schon alle Werte ausgerechnet sein.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19314
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 19.04.09 10:07 
user profile iconJonesAdams hat folgendes geschrieben Zum zitierten Posting springen:
Zitat:
Dann wirfst du berechnete Werte einfach weg. Wenn die erste Zeile nicht notwendig ist, wofür schreibst du die dann? :gruebel:
ausblenden Delphi-Quelltext
1:
2:
  b:=v/(a*c);
  b:=((o/2)-(a*c))/(a+c);


Das kapier ich ehrlich gesagt nicht.
In der ersten Zeile setzt du b auf einen bestimmten Wert, nämlich v/(a*c). In der zweiten Zeile überschreibst du den Wert wieder. Das Ergebnis aus der ersten Zeile wird also nie benutzt. Das sollte dir auch der Compiler sagen.

user profile iconJonesAdams hat folgendes geschrieben Zum zitierten Posting springen:
Naja... wenn die Werte vorher nicht in den Edits eingegeben wurden, bleiben sie doch auf "0". Doch irgendeine der Gleichungen wird doch funktionieren und daher das "until a<>0 ..." denn nach ein paar mal Hin-und-her-Gerechne werden schon alle Werte ausgerechnet sein.
Und was wenn in dem Beispiel von eben...
ausblenden Delphi-Quelltext
1:
2:
3:
 if a=0 then
  begin
  a:=v/(b*c);
...b oder c 0 sind? Durch Null kannst du ja nicht teilen. So klappt das nur, wenn du auch prüfst, ob die zur Berechnung benötigten Werte auch vorhanden sind.

Zudem ist bei Fließkommazahlen das Prüfen auf genau 0 schlecht, weil es auch 0,0000000000000001 sein kann, wegen einem Rundungsfehler. Denn die Zahlen werden intern ja binär gespeichert.
JonesAdams Threadstarter
Hält's aus hier
Beiträge: 7



BeitragVerfasst: So 19.04.09 10:17 
Ja...das Problem besteht ja darin, dass, wenn ich v, a und c mit der ersten Zeile rechnen muss, wenn ich aber o, a und c hab mit der zweiten Zeile rechnen muss... wie man das umgehen kann, ist die Frage...



Das mit dem durch Null teilen sind noch Schönheitsfehler, die ich mit if-Schleifen umgehen kann.



Gut, das mit den Fließkommazahlen auf Null prüfen kommt dann als Spaß nach der Arbeit auf mich zu, ist im Moment aber noch nicht soooooo wichtig.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19314
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 19.04.09 10:19 
user profile iconJonesAdams hat folgendes geschrieben Zum zitierten Posting springen:
Ja...das Problem besteht ja darin, dass, wenn ich v, a und c mit der ersten Zeile rechnen muss, wenn ich aber o, a und c hab mit der zweiten Zeile rechnen muss... wie man das umgehen kann, ist die Frage...
Indem du deine möglichen Formeln durchgehst und schaust für welche genügend Angaben vorhanden sind. Und wenn das der Fall ist, dann kannst du damit die Berechnung durchführen.
Für die restlichen Berechnungen ist die Schleife ja in Ordnung, wenn du immer schaust welche Angaben vorhanden und welche noch benötigt werden.

user profile iconJonesAdams hat folgendes geschrieben Zum zitierten Posting springen:
Das mit dem durch Null teilen sind noch Schönheitsfehler, die ich mit if-Schleifen umgehen kann.
if-schleife.de/
JonesAdams Threadstarter
Hält's aus hier
Beiträge: 7



BeitragVerfasst: So 19.04.09 10:30 
Vielen Dank :) , dank dir sind mir dann noch so einige Auswüchse meiner eigenen unkonzentrierten Arbeit aufgefallen :D :lol:

Das Skript funktioniert jetzt schon für ein paar Werte... einige Kombinationen scheinen nicht zu funktionieren:

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:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
unit QUADERSPECIAL;

interface

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

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit3: TEdit;
    Edit4: TEdit;
    Edit5: TEdit;
    Edit6: TEdit;
    Button1: TButton;
    Memo1: TMemo;
    Edit2: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var a,b,c,d,v,o: real;
begin
if Edit1.Text <> '' then
 begin
 a:=strtofloat(Edit1.Text);
 end;
if Edit2.Text <> '' then
 begin
 b:=strtofloat(Edit2.Text);
 end;
if Edit3.Text <> '' then
 begin
 c:=strtofloat(Edit3.Text);
 end;
if Edit4.Text <> '' then
 begin
 d:=strtofloat(Edit4.Text);
 end;
if Edit5.Text <> '' then
 begin
 v:=strtofloat(Edit5.Text);
 end;
if Edit6.Text <> '' then
 begin
 o:=strtofloat(Edit6.Text);
 end;

repeat
begin
 if b=0 then
  begin
   if ((a*b)<>0then
    begin
    b:=v/(a*c);
    end;
   if ((a+c)<>0then
    begin
    b:=((o/2)-(a*c))/(a+c);
    end;

   if (a<>0and (c<>0and (d<>0then
    begin
    b:=sqrt(sqr(d)-sqr(a)-sqr(c));
    end;

  end;


 if a=0 then
  begin
   if ((c*b)<>0then
    begin
    a:=v/(b*c);
    end;
   if ((b+c)<>0then
    begin
    a:=((o/2)-(b*c))/(b+c);
    end;

   if ((sqr(d)-sqr(b)-sqr(c))>0then
    begin
    a:=sqrt(sqr(d)-sqr(b)-sqr(c));
    end;

  end;


 if c=0 then
  begin
  if ((b*a)<>0then
   begin
   c:=v/(b*a);
   end;
  if  ((b+a)<>0then
   begin
   c:=((o/2)-(b*a))/(b+a);
   end;

   if ((sqr(d)-sqr(b)-sqr(a))>0then
    begin
    c:=sqrt(sqr(d)-sqr(b)-sqr(a));
    end;

  end;


 if d=0 then
  begin

   if ((sqr(a)+sqr(d)+sqr(c))>0then
    begin
    d:=sqrt(sqr(a)+sqr(d)+sqr(c));
    end;

  end;

 if o=0 then
  begin
  o:=2*(a*b+a*c+b*c);
  end;

 if v=0 then
 begin
 v:=a*b*c;
 end;

end;
until (a<>0and (b<>0and (c<>0and (d<>0and (o<>0and (v<>0);
memo1.Visible:= True;
Memo1.Clear;
Memo1.Lines.Add('Seitenlänge a         ' + FloatToStrF(a, fffixed, 10,2));
Memo1.Lines.Add('Seitenlänge b         ' + FloatToStrF(b, fffixed, 10,2));
Memo1.Lines.Add('Seitenlänge c         ' + FloatToStrF(c, fffixed, 10,2));
Memo1.Lines.Add('Diagonale d           ' + FloatToStrF(d, fffixed, 10,2));
Memo1.Lines.Add('Volumen V             ' + FloatToStrF(v, fffixed, 10,2));
Memo1.Lines.Add('Oberfläche O          ' + FloatToStrF(o, fffixed, 10,2));
end;

end.


Trotz des
Zitat:

ausblenden Delphi-Quelltext
1:
until (a<>0and (b<>0and (c<>0and (d<>0and (o<>0and (v<>0);					


kommen noch Null-Werte im Memo an... :gruebel:
JonesAdams Threadstarter
Hält's aus hier
Beiträge: 7



BeitragVerfasst: So 19.04.09 10:40 
Sorry, mein blöder Fehler...


So, wenn du mir hierfür das Okay gibst, dann dürfte alles klar sein! :)

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:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
unit QUADERSPECIAL;

interface

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

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit3: TEdit;
    Edit4: TEdit;
    Edit5: TEdit;
    Edit6: TEdit;
    Button1: TButton;
    Memo1: TMemo;
    Edit2: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var a,b,c,d,v,o: real;
begin
if Edit1.Text <> '' then
 begin
 a:=strtofloat(Edit1.Text);
 end;
if Edit2.Text <> '' then
 begin
 b:=strtofloat(Edit2.Text);
 end;
if Edit3.Text <> '' then
 begin
 c:=strtofloat(Edit3.Text);
 end;
if Edit4.Text <> '' then
 begin
 d:=strtofloat(Edit4.Text);
 end;
if Edit5.Text <> '' then
 begin
 v:=strtofloat(Edit5.Text);
 end;
if Edit6.Text <> '' then
 begin
 o:=strtofloat(Edit6.Text);
 end;

repeat
begin
 if b=0 then
  begin
   if ((a*b)<>0then
    begin
    b:=v/(a*c);
    end;
   if ((a+c)<>0then
    begin
    b:=((o/2)-(a*c))/(a+c);
    end;

   if ((sqr(d)-sqr(a)-sqr(c))>0then
    begin
    b:=sqrt(sqr(d)-sqr(a)-sqr(c));
    end;

  end;


 if a=0 then
  begin
   if ((c*b)<>0then
    begin
    a:=v/(b*c);
    end;
   if ((b+c)<>0then
    begin
    a:=((o/2)-(b*c))/(b+c);
    end;

   if ((sqr(d)-sqr(b)-sqr(c))>0then
    begin
    a:=sqrt(sqr(d)-sqr(b)-sqr(c));
    end;

  end;


 if c=0 then
  begin
  if ((b*a)<>0then
   begin
   c:=v/(b*a);
   end;
  if  ((b+a)<>0then
   begin
   c:=((o/2)-(b*a))/(b+a);
   end;

   if ((sqr(d)-sqr(b)-sqr(a))>0then
    begin
    c:=sqrt(sqr(d)-sqr(b)-sqr(a));
    end;

  end;


 if d=0 then
  begin

   if ((sqr(a)+sqr(d)+sqr(c))>0then
    begin
    d:=sqrt(sqr(a)+sqr(d)+sqr(c));
    end;

  end;

 if o=0 then
  begin
  o:=2*(a*b+a*c+b*c);
  end;

 if v=0 then
 begin
 v:=a*b*c;
 end;

end;
until (a<>0and (b<>0and (c<>0and (d<>0and (o<>0and (v<>0);
memo1.Visible:= True;
Memo1.Clear;
Memo1.Lines.Add('Seitenlänge a         ' + FloatToStrF(a, fffixed, 10,2));
Memo1.Lines.Add('Seitenlänge b         ' + FloatToStrF(b, fffixed, 10,2));
Memo1.Lines.Add('Seitenlänge c         ' + FloatToStrF(c, fffixed, 10,2));
Memo1.Lines.Add('Diagonale d           ' + FloatToStrF(d, fffixed, 10,2));
Memo1.Lines.Add('Volumen V             ' + FloatToStrF(v, fffixed, 10,2));
Memo1.Lines.Add('Oberfläche O          ' + FloatToStrF(o, fffixed, 10,2));
end;

end.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19314
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 19.04.09 11:15 
Sicher?
user profile iconJonesAdams hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
 if d=0 then
  begin

   if ((sqr(a)+sqr(d)+sqr(c))>0then
    begin
    d:=sqrt(sqr(a)+sqr(d)+sqr(c));
    end;


Wie wäre es insgesamt so?
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:
procedure TForm1.btnStartClick(Sender: TObject);

  function CalcSide(var Side: Single; const Side1, Side2, Volume, Diagonal, Surface: Single;
    const Side1Valid, Side2Valid, VolumeValid, DiagonalValid, SurfaceValid: Boolean): Boolean;
  begin
    Result := True;
    if VolumeValid and Side1Valid and Side1Valid and (Side1 * Side2 <> 0then
      Side := Volume / (Side1 * Side2)
    else if SurfaceValid and Side1Valid and Side2Valid and (Side1 + Side2 <> 0then
      Side := ((Surface / 2) - (Side1 * Side2)) / (Side1 + Side2)
    else if Side1Valid and Side2Valid and DiagonalValid then
      Side := Sqrt(Sqr(Diagonal) - Sqr(Side1) - Sqr(Side2))
    else
      Result := False;
  end;

var
  a, b, c, d, v, o: Single;
  av, bv, cv, dv, vv, ov: Boolean; // are the values valid
begin
  av := TryStrToFloat(edtSideA.Text, a);
  bv := TryStrToFloat(edtSideB.Text, b);
  cv := TryStrToFloat(edtSideC.Text, c);
  dv := TryStrToFloat(edtDiagonal.Text, d);
  vv := TryStrToFloat(edtVolume.Text, v);
  ov := TryStrToFloat(edtSurface.Text, o);

  repeat
    if not av then
      av := CalcSide(a, b, c, v, d, o, bv, cv, vv, dv, ov);
    if not bv then
      bv := CalcSide(b, a, c, v, d, o, av, cv, vv, dv, ov);
    if not cv then
      cv := CalcSide(c, a, b, v, d, o, av, bv, vv, dv, ov);
    if not dv and av and bv and cv then
    begin
      d := Sqrt(Sqr(a) + Sqr(b) + Sqr(c));
      dv := True;
    end;
    if not ov and av and bv and cv then
    begin
      o := 2 * (a * b + a * c + b * c);
      ov := True;
    end;
    if not vv and av and bv and cv then
    begin
      v := a * b * c;
      vv := True;
    end;
  until av and bv and cv and dv and ov and vv;
  memResult.Visible := True;
  memResult.Clear;
  memResult.Lines.Add('Seitenlänge a         ' + FloatToStrF(a, fffixed, 10,2));
  memResult.Lines.Add('Seitenlänge b         ' + FloatToStrF(b, fffixed, 10,2));
  memResult.Lines.Add('Seitenlänge c         ' + FloatToStrF(c, fffixed, 10,2));
  memResult.Lines.Add('Diagonale d           ' + FloatToStrF(d, fffixed, 10,2));
  memResult.Lines.Add('Volumen V             ' + FloatToStrF(v, fffixed, 10,2));
  memResult.Lines.Add('Oberfläche O          ' + FloatToStrF(o, fffixed, 10,2));
end;
// EDIT: Tippfehler korrigiert.


Zuletzt bearbeitet von jaenicke am So 19.04.09 11:30, insgesamt 1-mal bearbeitet
koegi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 18

Win 7 64 bit
Delphi 2009 Professional
BeitragVerfasst: So 19.04.09 11:28 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:

Allgemeiner Tipp: Es gibt auch TryStrToFloat statt den vielen ifs am Anfang, womit du auch falsche Eingaben (keine Zahlen) abfängst.


Vielen Dank für den Tipp! Die Try...-Funktionen kannte ich bisjetzt noch nicht!

Gruß

Thomas
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19314
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 19.04.09 11:32 
Da waren noch zwei Tipp- bzw. C&P-Fehler beim Aufruf von CalcSide, ich habs im letzten Beitrag korrigiert.

user profile iconkoegi hat folgendes geschrieben Zum zitierten Posting springen:
Vielen Dank für den Tipp! Die Try...-Funktionen kannte ich bisjetzt noch nicht!
Ja, die sind recht nützlich. ;-)
Mitmischer 1703
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 754
Erhaltene Danke: 19

Win 7, Debian
Delphi Prism, Delphi 7, RAD Studio 2009 Academic, C#, C++, Java, HTML, PHP
BeitragVerfasst: So 19.04.09 11:33 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Zudem ist bei Fließkommazahlen das Prüfen auf genau 0 schlecht, weil es auch 0,0000000000000001 sein kann, wegen einem Rundungsfehler. Denn die Zahlen werden intern ja binär gespeichert.


Dafür gibt's IfZero

_________________
Die Lösung ist nicht siebzehn.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19314
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 19.04.09 11:40 
user profile iconMitmischer 1703 hat folgendes geschrieben Zum zitierten Posting springen:
Dafür gibt's IfZero
Das ist aber keine delphiinterne Funktion, oder? :gruebel:
Oder ist die bei neueren Versionen neu dabei oder in einer anderen Unit?
Mitmischer 1703
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 754
Erhaltene Danke: 19

Win 7, Debian
Delphi Prism, Delphi 7, RAD Studio 2009 Academic, C#, C++, Java, HTML, PHP
BeitragVerfasst: So 19.04.09 11:45 
Unit Math?

Die Funktion gibt an, ob eine Gleitkommavariable oder ein Gleitkommaausdruck den Wert Null oder beinahe Null hat.

Unit

Math

Kategorie

Arithmetik

Delphi-Syntax:

function IsZero(const A: Single; Epsilon: Single = 0): Boolean; overload;
function IsZero(const A: Double; Epsilon: Double = 0): Boolean; overload;
function IsZero(const A: Extended; Epsilon: Extended = 0): Boolean; overload;

C++ Syntax:

extern PACKAGE bool __fastcall IsZero(const float A, float Epsilon);
extern PACKAGE bool __fastcall IsZero(const double A, double Epsilon);
extern PACKAGE bool __fastcall IsZero(const Extended A, Extended Epsilon);

Beschreibung

Mit IsZero können Sie prüfen, ob AValue Null oder von Null um nicht mehr als Epsilon entfernt ist.

_________________
Die Lösung ist nicht siebzehn.
JonesAdams Threadstarter
Hält's aus hier
Beiträge: 7



BeitragVerfasst: So 19.04.09 11:46 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Sicher?
user profile iconJonesAdams hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
 if d=0 then
  begin

   if ((sqr(a)+sqr(d)+sqr(c))>0then
    begin
    d:=sqrt(sqr(a)+sqr(d)+sqr(c));
    end;


Wie wäre es insgesamt so?
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:
procedure TForm1.btnStartClick(Sender: TObject);

  function CalcSide(var Side: Single; const Side1, Side2, Volume, Diagonal, Surface: Single;
    const Side1Valid, Side2Valid, VolumeValid, DiagonalValid, SurfaceValid: Boolean): Boolean;
  begin
    Result := True;
    if VolumeValid and Side1Valid and Side1Valid and (Side1 * Side2 <> 0then
      Side := Volume / (Side1 * Side2)
    else if SurfaceValid and Side1Valid and Side2Valid and (Side1 + Side2 <> 0then
      Side := ((Surface / 2) - (Side1 * Side2)) / (Side1 + Side2)
    else if Side1Valid and Side2Valid and DiagonalValid then
      Side := Sqrt(Sqr(Diagonal) - Sqr(Side1) - Sqr(Side2))
    else
      Result := False;
  end;

var
  a, b, c, d, v, o: Single;
  av, bv, cv, dv, vv, ov: Boolean; // are the values valid
begin
  av := TryStrToFloat(edtSideA.Text, a);
  bv := TryStrToFloat(edtSideB.Text, b);
  cv := TryStrToFloat(edtSideC.Text, c);
  dv := TryStrToFloat(edtDiagonal.Text, d);
  vv := TryStrToFloat(edtVolume.Text, v);
  ov := TryStrToFloat(edtSurface.Text, o);

  repeat
    if not av then
      av := CalcSide(a, b, c, v, d, o, bv, cv, vv, dv, ov);
    if not bv then
      bv := CalcSide(b, a, c, v, d, o, av, cv, vv, dv, ov);
    if not cv then
      cv := CalcSide(c, a, b, v, d, o, av, bv, vv, dv, ov);
    if not dv and av and bv and cv then
    begin
      d := Sqrt(Sqr(a) + Sqr(b) + Sqr(c));
      dv := True;
    end;
    if not ov and av and bv and cv then
    begin
      o := 2 * (a * b + a * c + b * c);
      ov := True;
    end;
    if not vv and av and bv and cv then
    begin
      v := a * b * c;
      vv := True;
    end;
  until av and bv and cv and dv and ov and vv;
  memResult.Visible := True;
  memResult.Clear;
  memResult.Lines.Add('Seitenlänge a         ' + FloatToStrF(a, fffixed, 10,2));
  memResult.Lines.Add('Seitenlänge b         ' + FloatToStrF(b, fffixed, 10,2));
  memResult.Lines.Add('Seitenlänge c         ' + FloatToStrF(c, fffixed, 10,2));
  memResult.Lines.Add('Diagonale d           ' + FloatToStrF(d, fffixed, 10,2));
  memResult.Lines.Add('Volumen V             ' + FloatToStrF(v, fffixed, 10,2));
  memResult.Lines.Add('Oberfläche O          ' + FloatToStrF(o, fffixed, 10,2));
end;
// EDIT: Tippfehler korrigiert.


Sorry, war mein fehler... Formel ist natürlich sqrt(a²+b²+c²)...


Wow... vielen Dank für diese Verbesserung... mit den Funktionen ist es natürlich viel übersichtlicher :) :) :) :) :)


IsZero kannte ich gar nicht.........




// EDIT: Vielen vielen Dank für die großartige Hilfe!!!