Entwickler-Ecke

Sonstiges (Delphi) - Schleifenproblem


Fluffy - Mi 09.02.05 14:33
Titel: Schleifenproblem
Wir haben ein kleines (oder großes) Problem :cry: mit einer Schleife, die nicht durchlaufen wird!
Das Problem ist unserer Meinung nach am Anfang bei x>1/10

Hier der Quelltext (Auszug):

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
while x>1/10 do
    begin
      s:=z-(p*a-p*z)/(x-p);
      a:=s;
      for i:= 1 to n-1 do
        begin
          g:=g+3;
          if stringgrid1.cells[g-3,0]<>'-' then
              y:=power(a,(strtoint(stringgrid1.cells[g-1,0])))*(strtoint(stringgrid1.cells[g-2,0]))
           else
              y:=-power(a,(strtoint(stringgrid1.cells[g-1,0])))*(strtoint(stringgrid1.cells[g-2,0]));
         x:=x+y;
       end;
    end;
  label10.Caption:=floattostr(x);
  label9.Caption:=floattostr(s);


Auszug Ende

Zwei arme unwissende Schüler :flehan: würden sich über Hilfe freuen...

Moderiert von user profile iconUdontknow: Delphi-Tags hinzugefügt.


Udontknow - Mi 09.02.05 14:41

Hallo!

Lasst doch einfach mal x vor der Schleife durch ShowMessage ausgeben.


Delphi-Quelltext
1:
ShowMessage(FormatFloat('0.000',x));                    


Cu,
Udontknow


Fluffy - Mi 09.02.05 14:44

X wird vorher bei uns berechnet und liegt (meistens) über 1.
Wir haben schon versucht while abs(x)>1/10 do zu schreiben, geht aber nicht.

Wir haben keinen Schimmer, was falsch ist... :bawling:


Lossy eX - Mi 09.02.05 14:45

Mal ne ganz Doofe frage ohne die wir euer Problem nicht verstehen können. Was habt ihr eigentlich damit vor? Und vor allem wo kommen denn die Variablen her? Bzw was steht drin?

PS: While führt die Schleife so lange aus wie die Bedingung erfüllt ist. Wenn X also zu begin 0 ist dann wird sie nie ausgeführt. Das nur mal am Rande.

[edit] Hat sich überschnitten. Vergesst das mit X.


IngoD7 - Mi 09.02.05 14:47
Titel: Re: Schleifenproblem!!!
Fluffy hat folgendes geschrieben:

Das Problem ist unserer Meinung nach am Anfang bei x>1/10
Darauf dürft ihr wetten. Es ist schließlich die einzig steuernde Bedingung für die Schleife.

Da aber x abhängig von y ist, welches widerum über Inhalte eines StringGrids bestimmt wird, die keiner hier kennt, werden wir nicht helfen können.

Ich würde Haltepunkte setzen und/oder Variablenwerte verfolgen, um zu sehen, wo und warum x unerwartet kleiner 0,1 wird.


Udontknow - Mi 09.02.05 14:48

Das Problem muss näher beschrieben werden. Was genau klappt an dem Code nicht? Was wollt ihr überhaupt erreichen? Evtl noch mehr Code posten. Was klappt an "Abs(x)>1/10" nicht?

Lasst euch bei der Fehlersuche immer wieder Infos ausgeben (entweder über ShowMessage oder aber besser Zeilen in ein Memofeld einfügen). Ihr könnt natürlich auch mit Breakpoints arbeiten.

Cu,
Udontknow


Fluffy - Mi 09.02.05 14:49

Das Programm stellt das Sekantenverfahren dar, um Nullstellen einer beliebigen ganzrationalen Funktion zu bestimmen.
Die Variablen sind von einer(!) Punktberechnung (y-Wert).

Sollen wir den ganzen Quelltext schicken?


AXMD - Mi 09.02.05 14:50

1.) Deine !-Taste ist kaputt (Titel!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!) - hoppla, meine ist ja auch kaputt :D

2.) Ein aus dem Zusammenhang gerissenes Stück Code sagt wenig aus...

AXMD


Fluffy - Mi 09.02.05 14:59

ok. Leute mal soviel, wir sind zwei ziemlich unerfahrene Schüler, die mit diesem Delphiprogramm belastet wurden und damit einfach nicht klarkommen!!!!

Hier erstmal der Quelltext:

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:
var
  Form1: TForm1;
   var a,s,c,x,y,o,p : real;
n,f,z:integer;
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
f:=f+3;
stringgrid1.Cells[f-1,0]:=edit2.text;
stringgrid1.cells[f,0]:=edit1.text;
stringgrid1.cells[f-2,0]:=edit3.text;
end;



procedure TForm1.Button3Click(Sender: TObject);
begin
f:=-1;
n:=strtoint(edit1.Text);
stringgrid1.colcount:=3*n+3;
label5.Visible:=false;
edit4.Visible:=false;
edit5.Visible:=false;
label6.Visible:=false;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
label5.Visible:=true;
edit4.Visible:=true;
edit5.Visible:=true;
label6.Visible:=true;
end;

procedure TForm1.Button4Click(Sender: TObject);
var i,g: integer;
begin
  a:=strtofloat(edit4.text);
  z:=strtoint(edit5.text);
  edit4.Visible:=false;
  label5.visible:=false;
  edit5.Visible:=false;
  label6.Visible:=false;
  g:=0;
  y:=0;
  o:=0;
  x:=0;
  for i:= 1 to n+1 do
    begin
      g:=g+3;
      if stringgrid1.cells[g-3,0]<>'-' then
        begin
          o:=power(z,(strtoint(stringgrid1.cells[g-1,0])))*(strtoint(stringgrid1.cells[g-2,0]));
          y:=power(a,(strtoint(stringgrid1.cells[g-1,0])))*(strtoint(stringgrid1.cells[g-2,0]));
         end
      else
        begin
          o:=-power(z,(strtoint(stringgrid1.cells[g-1,0])))*(strtoint(stringgrid1.cells[g-2,0]));
          y:=-power(a,(strtoint(stringgrid1.cells[g-1,0])))*(strtoint(stringgrid1.cells[g-2,0]));
        end;
    p:=p+o;
    x:=x+y;
     end;
    label7.caption:=floattostr(x);
    label8.caption:=floattostr(p);


  g:=0;
  y:=0;
   while abs(x)>1/10 do
    begin
      s:=z-(p*a-p*z)/(x-p);
      a:=s;
      for i:= 1 to n-1 do
        begin
          g:=g+3;
          if stringgrid1.cells[g-3,0]<>'-' then
              y:=power(a,(strtoint(stringgrid1.cells[g-1,0])))*(strtoint(stringgrid1.cells[g-2,0]))
           else
              y:=-power(a,(strtoint(stringgrid1.cells[g-1,0])))*(strtoint(stringgrid1.cells[g-2,0]));
         x:=x+y;
       end;
    end;
  label10.Caption:=floattostr(x);
  label9.Caption:=floattostr(s);
end;

end.


bei while abs(x)... kommt die Fehlermeldung, kein gültiger Integerwert. Braucht abs Integerwerte?
Wir wären über etwas(viel) Unterstützung total Dankbar...

Moderiert von user profile iconAXMD: Delphi-Tags hinzugefügt.


Lossy eX - Mi 09.02.05 15:01

Mir ist da gerade was aufgefallen.

Delphi-Quelltext
1:
2:
3:
4:
5:
      for i:= 1 to n-1 do
        begin
          g:=g+3;
          if stringgrid1.cells[g-3,0]<>'-' then
              y:=power(a,(strtoint(stringgrid1.cells[g-1,0])))*(strtoint(stringgrid1.cells[g-2,0]))

Wo initialisiert ihr g? Sollte das nicht vor jedem Schleifendurchlauf wieder auf den Anfang gesetzt werden? Also vor den von mir geposteten Codes? Sonst wandert ihr in eurem Stringgrid immer weiter nach rechts. Wenn ihr aber die Funktion (innere Schleife) häufiger ausführen wollt, so müsstet ihr ja immer am anfang wieder anfangen. Korrigiert mich wenn ich falsch liege.


Fluffy - Mi 09.02.05 15:03

Gut erkannt, aber g soll immer um 3 Felder nach rechts laufen.


Delete - Mi 09.02.05 15:06

Hab mal ne Facharbeit zum Thema "Iterationsverfahren zur Nullstellenbestimmung" geschrieben. Da hab ich das unter anderen auch das Sekantenverfahren beschrieben und dazu ein Delphiprogramm geschrieben, aber bei mir hats geklappt :-). Würde euch gerne den Teil zur Verfügung stellen, ist aber zu Hause, also wird das vor Sonntag nichts..


AXMD - Mi 09.02.05 15:07

1.) Die Rufzeichen aus dem Titel, aber schnell :evil:

2.)
Fluffy hat folgendes geschrieben:
Gut erkannt, aber g soll immer um 3 Felder nach rechts laufen.
Das hat ihn nicht interessiert. Das
Lossy eX hat folgendes geschrieben:
Wo initialisiert ihr g? Sollte das nicht vor jedem Schleifendurchlauf wieder auf den Anfang gesetzt werden?
war seine Frage

und 3.) nächstes Mal bitte Delphi-Tags verwenden, danke :)

AXMD


Fluffy - Mi 09.02.05 15:10

Also, wenn wir gar nichts anderes hinkriegen (hoffen wir nicht), dann wäre das hilfreich, gut, nett, super, toll, cool + weitere positive Adjektive.

e-mail: ann.wild@web.de

Danke, danke danke!!!


Lossy eX - Mi 09.02.05 15:10

Für jeden Schleifendurchgang in der FOR Schleife? Das dachte ich mir. Wenn das vor der WHILE Schleife aber nicht wieder auf 0 gesetzt wird dann rennt er immer und immer weiter nach recht. Soll das so sein?
Wie sehen denn eure StringGriddaten aus? Also nur so zum Verständnis.


Fluffy - Mi 09.02.05 15:13

Sieh dir mal den langen, langen (und noch längeren) Quelltext Nr. 2 an, dort steht vor der while-Schleife einmal g:=0.


AXMD - Mi 09.02.05 15:14

Fluffy, sag mal, bist du blind oder kannst du nicht lesen?

AXMD hat folgendes geschrieben:
1.) Die Rufzeichen aus dem Titel, aber schnell :evil:


Öfter als dreimal weis ich dich nicht drauf hin :evil:

AXMD


Fluffy - Mi 09.02.05 15:16

Wo??? Wie???
Wo bekommt die drei! raus?


Udontknow - Mi 09.02.05 15:18

Einfach oben beim ersten Post auf "Edit" klicken, dann den Titel korrigieren und abspeichern.

Cu,
Udontknow


Lossy eX - Mi 09.02.05 15:27

Fluffy hat folgendes geschrieben:
Sieh dir mal den langen, langen (und noch längeren) Quelltext Nr. 2 an, dort steht vor der while-Schleife einmal g:=0.

Du hast Glück. Ich bin heute sehr geduldig. Noch...

Wo g her kommt weiß ich. ABER. Meine eigentliche Frage seit 2 Posts ist die ob es so gewollt ist, dass du mit g immer weiter nach Rechts gehst?

Mal in einem Beispiel verdeutlicht. Wenn du 5 Wertetrible (3 Werte) hast, dann macht das insgesammt 15 Werte. Das sind dann also 15 Spalten. Wenn du nun bei dieser Funktion nun einen Nullpunkt suchst, dann müsstest du diese 15 Werte z.b. 100 mal aufeinerrechnen. Ja? Das würde also bedeuten, dass du mit deiner FOR Schleife immer wieder an den Anfang deiner Werte anfangen müsstest?

Soll also bedeuten du müsstest g vor der FOR Schleife immer wieder zurücksetzen damit du immer wieder am Anfang deiner Werte beginnst. Anderfalls würdest du versuchen in nicht beschriebene Felder des Stringgrids zuzugreifen. Was auch den Fehler "kein gültiger Integerwert" erklären würde. Ich denke nämlich mal, dass du dort versucht hast einen leeren Text in einen Integer zu wandeln. Was natürlich nicht geht.


Fluffy - Mi 09.02.05 15:36

Also, wir berechnen Punkte.
In der ersten Schleife funktioniert der Vorgang
g:=0;
For-Schleife
Rest

IN der zweiten gehts nicht, obwohl vom Aufbau her alles gleich ist.
UND: Ja, g soll nach jedem einzelnen Schleifendurchlauf 3 Felder nach rechts gehen. Alle Werte aus dem Stringgrid werden multipliziert bzw. als Potenz genommen.
(Dieser Teil funktionierte allerdings noch).


Lossy eX - Mi 09.02.05 15:47

Okay. Vielleicht war das ein bisschen verwirrend. Die erste FOR Schleife berechnet den ersten Punkt. Vor der While Schleife setzt du g noch einmal auf 0 und dort sollte dann der erste Durchgang auch noch klappen. Allerdings der Zweite nicht. Ziehe das g := 0 wie markiert mal in die while Schleife.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
  y:=0;
   while abs(x)>1/10 do
    begin
      s:=z-(p*a-p*z)/(x-p);
      a:=s;
      g:=0;
      for i:= 1 to n-1 do
        begin
          g:=g+3;
          if stringgrid1.cells[g-3,0]<>'-' then
              y:=power(a,(strtoint(stringgrid1.cells[g-1,0])))*(strtoint(stringgrid1.cells[g-2,0]))
           else
              y:=-power(a,(strtoint(stringgrid1.cells[g-1,0])))*(strtoint(stringgrid1.cells[g-2,0]));
         x:=x+y;
       end;
    end;


PS: Irgendwie habe ich von deinem letzten Post nur maximal die Hälfte verstanden.


Fluffy - Mi 09.02.05 15:58

Danke für deinen Hinweis,...
wenigstens rechnet er jetzt wenigstens, wenn auch falsch


Fluffy - Do 10.02.05 11:00

Wir haben mittlerweile (antwortet ja keiner... :cry: ) einige Sachen hingekriegt, sind im Moment aber dabei, die erste Ableitung auf Nullstellen zu prüfen. (Ein Abbruchkriterium.)
Die Schleife soll einen bestimmten Bereich überprüfen, ob in diesem Intervall die Funktion irgendwann mal 0 wird (z.B. ob 3x^2 +5=0 möglich ist)

Das Problem ist folgendes: Bei einer Schleife kann man (?) doch nur Integer-Werte durchlaufen lassen, wie kann man mit kleineren Abständen prüfen lassen (z.B. 0,1)???

Bitte meldet euch :!:


Delete - Do 10.02.05 11:15

indem man die Zählvariable in der Schleife teilt:


Delphi-Quelltext
1:
2:
3:
4:
 for n := 1 to 1000 do
begin
  temp := n/10;
end;


wobei temp zb vom typ double ist..


jasocul - Do 10.02.05 11:23

Oder man nimmt eine while-Schleife (Repeat..until geht natürlich auch) und sorgt selbst für das Hochzählen.


Fluffy - Do 10.02.05 11:33

Danke davör...
sind noch am ausprobieren, könnt aber klappen!! :D


Fluffy - Do 10.02.05 11:44

Ok, hier das aktuellste Problem: :gruebel:

for n:= Ax to Bx do
....

wobei Ax und Bx vom Typ Real sind.

Eigentlich sollte n nun in 0,1-Schritten laufen, wie geht das mit Real??


jasocul - Do 10.02.05 11:48

gar nicht.
Ax und Bx müssen Cardinal sein. Also Integer, Word o.ä.
Lies doch mal den Beitrag von OneOfTen.


Fluffy - Do 10.02.05 11:54

Cardinal-Werte sind nur im positiven Bereich verfügbar, unsere Variablen sollen aber negativ sein, WIE IST DAS REALISIERBAR??????? :bawling:


jasocul - Do 10.02.05 12:04

Kleiner Fehler meinerseits.
Nimm Integer. Hatte ich aber auch dazu geschrieben.


Fluffy - Do 10.02.05 12:34

Wie kann man eine Schleife abbrechen, sobald eine if Bedingung erfüllt ist??


jasocul - Do 10.02.05 12:35

Break
Oder eine while-Schleife verwenden


Fluffy - Do 10.02.05 12:40

Danke!! :D