Autor Beitrag
Ottchen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 43



BeitragVerfasst: Mi 20.11.02 20:06 
Hallo Liste!

Ich habe mal wieder ein Problem mit der Austrittsbedingung der Repeat-Until-Schleife. Der größte gemeinsame Teiler zweier Zahlen soll nach dem Algorithmus von EUKLID ermittelt werden. Wenn die Restdivision Null ergibt, soll die Schleife beendet sein. Gebe ich z.B. die Zahlen 24 und 12 ein, kommt sofort das Ergebnis 3 und der Rest Null wird auch im StringGrid ausgegeben.

Hier der QT:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
procedure TForm1.Rechne1Click(Sender: TObject);
var a, b, i, Rest, quotient:integer;
begin
  a:=StrToInt(a_Edit.Text);
  b:=StrToInt(b_Edit.Text);

  if a<b then MessageDlg('a muss größer als b sein!',mtInformation,[mbOK],0)
  else begin
         i:=1;
         repeat
           StringGrid1.RowCount:=i+1;
           StringGrid1.Cells[0,i]:=IntToStr(i);
           StringGrid1.Cells[1,i]:=IntToStr(a); // dient nur der Ausgabe
           StringGrid1.Cells[2,i]:=IntToStr(b); // dient nur der Ausgabe
           quotient:=a DIV b; // dient nur der Ausgabe
           StringGrid1.Cells[3,i]:=IntToStr(quotient); // dient nur der       Ausgabe
           Rest:=a MOD b;
           StringGrid1.Cells[4,i]:=IntToStr(Rest); // dient nur der Ausgabe
           i:=i+1;
          until Rest=0;
        end; {of begin Zeile 52}
  ausgabe_panel.caption:=IntToStr(b);
end;




Findet Ihr einen Fehler? :shock:

Danke!!!!
Ottchen

_________________
See you.
tommie-lie
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 4373

Ubuntu 7.10 "Gutsy Gibbon"

BeitragVerfasst: Mi 20.11.02 20:59 
Hast du schonmal was von Trace und Step und der Watch-List gehört?

Anscheinend nicht, denn:
Wenn du dir die Werte im Debugger mal anschaust, wird dir kalr, warum die Schleife endlos durchgelaufen wird, sobald Rest <> 0 ist:
Zuerst führst du die Integer-Division von a \ b durch (nicht zu verwechseln mit der Fließkommadivision a / b). Dadurch hast du den ganzzahligen Wert des Quotienten a : b. An den Werten veränderst du nichts.
Ich habe es bei mir mal mit 143 und 12 ausprobiert. Ergebnis: 11
Dann holst du dir mit mod den Rest der Integer-Division. Bei mir auch 11. Dann guckst du, ob Rest = o ist. Ist nicht, also nochmal das ganze. Wieder 143 div 12, wieder 11. Wieder 143 mod 12. Wieder Rest 11. Immer noch nicht 0, also wieder 143 mod 12, immer noch nicht 0, also wieder 143 mod 12.
Klar?
Wenn eine Zahl nicht ohne Rest teilbar ist, wird die Schleife immer ausgeführt, weil du die Werte nie änderst, er also immer wieder nicht 0 ist.

Tschüß
Thomas

_________________
Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
Funzi
Hält's aus hier
Beiträge: 11



BeitragVerfasst: Mi 20.11.02 22:08 
Titel: while-Schleife
Also... ich glaube das Problem lässt sich lösen, indem man anstatt der repeat-Schleife eine while-Schleife benutzt.

Habe es nicht ausprobiert, aber erst vor kurzem eine Arbeit darüber geschrieben. Also ich hab deinen QT mal geringfügig verändert...

Probiers mal aus!

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
...
while Rest <> 0 do
  begin
    StringGrid1.RowCount:=i+1;
    quotient:=a DIV b;
    Rest:=a MOD b;
    i:=i+1;
  end;


Feedback erwünscht!

_________________
Der Reboot:

Bei Linux hilfreich, aber nicht zwingend notwendig.
Bei Windows notwendig, aber nicht zwingend hilfreich.
Wolff68
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 302
Erhaltene Danke: 1

WinXP home
D6 Prof
BeitragVerfasst: Do 21.11.02 08:05 
Und was soll sich nun dadurch ändern? Ausser, daß Du vorher nun auch noch den Rest mit einem Wert <> 0 initialisieren musst?

Hast Du über 1 Stunde geschrieben? Oder warum baust Du genau den gleichen Fehler ein, den tommie bereits erklärt hatte?

Egal ob While oder Repeat. Wichtig ist immer, daß sich der Wert der Abbruchbedingung auch Ändert !!!
Wenn a MOD b ungleich 0 ist kannst es so oft rechnen wie Du willst. Solange sich weder bei a noch b was ändert wird das Ergebnis <>0 immer das gleiche bleiben.

_________________
"Der Mensch ist nicht was er sich vorstellt oder wünscht zu sein, sondern das was andere in ihm sehen."
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 21.11.02 11:09 
Wolff68 hat folgendes geschrieben:
Wichtig ist immer, daß sich der Wert der Abbruchbedingung auch Ändert !!!


Oder um genauer zu sein: Sie muß irgendwann mal erfüllt sein. Eigentlich nicht genauer, sondern richtiger. Wenn sie sich ändert heißt, dass nicht, dass sie auch mal greift.


Zuletzt bearbeitet von Luckie am Do 21.11.02 11:33, insgesamt 1-mal bearbeitet
UGrohne
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Veteran
Beiträge: 5502
Erhaltene Danke: 220

Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
BeitragVerfasst: Do 21.11.02 11:31 
Hab mal in meinem Info-Archiv gestöbert und folgendes gefunden:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
function tform1.ggt(a,b : integer):integer;
var rest: integer;
begin
     repeat
          rest:= a mod b;
          a:= b;
          b:= rest;
     until    rest= 0;
              ggt:= a;
end;


Hoffe, das hilft weiter
Ottchen Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 43



BeitragVerfasst: Do 21.11.02 17:52 
Titel: Ihr habt ja alle Recht :--))
Ja logisch!!

Das kann ja auch nicht funktionieren, weil ich einfach zu unkonzentriert und müde war, so dass zwei Anweisungen für den EUKLID-Algor. fehlen! Mensch!

Hier der richtige Quelltext (so wie ihn UGrohne auch beschrieb):

ausblenden 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:
procedure TForm1.Rechne1Click(Sender: TObject);
var a, b, i, Rest, quotient:integer;
begin
  a:=StrToInt(a_Edit.Text);
  b:=StrToInt(b_Edit.Text);

  if a<b then MessageDlg('a muss größer als b sein!',mtInformation,[mbOK],0)
  // oder ganz einfach den folgenden Teil nehmen und Rest:=b MOD a rechnen
  else begin
         i:=1;
         repeat
           StringGrid1.RowCount:=i+1;
           StringGrid1.Cells[0,i]:=IntToStr(i);
           StringGrid1.Cells[1,i]:=IntToStr(a);
           StringGrid1.Cells[2,i]:=IntToStr(b);
           quotient:=a DIV b;
           StringGrid1.Cells[3,i]:=IntToStr(quotient);
           Rest:=a MOD b;
           StringGrid1.Cells[4,i]:=IntToStr(Rest);
           a:=b;
           b:=Rest;
           i:=i+1;
          until Rest=0;
        end; {of begin Zeile 52}
  ausgabe_panel.caption:=IntToStr(a);
end;


:arrow: Danke an alle!

Und von Trace und Step und der Watch-List habe ich wirklich nichts gehört; bin aber für jeden Tipp dankbar. :wink:

Ottchen

_________________
See you.
UGrohne
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Veteran
Beiträge: 5502
Erhaltene Danke: 220

Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
BeitragVerfasst: Do 21.11.02 18:04 
Nochn kleiner Tipp von nem Schreibfaulen: Mach statt
ausblenden Quelltext
1:
i:=i+1;					

einfach
ausblenden Quelltext
1:
Inc(i);					


Macht dasselbe, aber sieht schöner aus *g*
Wolff68
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 302
Erhaltene Danke: 1

WinXP home
D6 Prof
BeitragVerfasst: Do 21.11.02 19:17 
Titel: Watchlist, Trace, Step
Also was tommie gemeint hat ist das Schrittweise Ausführen des Programmes während man die Variablen im Auge behält.

Auf Deutschen Systemen zu finden unter Start / Einzelne Anweisung ....
Die Watchlist ist das Fenster mit den Überwachten Ausdrücken.
Findet man unter Ansicht / Debugfenster / Überwachte Ausdrücke

Am besten setzt Du Dir in die Schleife oder davor einen Haltepunkt und gehst dann die Programmschritte einzeln mit F7 durch.

_________________
"Der Mensch ist nicht was er sich vorstellt oder wünscht zu sein, sondern das was andere in ihm sehen."
tommie-lie
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 4373

Ubuntu 7.10 "Gutsy Gibbon"

BeitragVerfasst: Do 21.11.02 19:35 
Jepp.
Der Unterschied zwischen Trace und Step ist nur, daß Trace auch die Zeilen einzeln bearbeitet, die in Funktionen zu finden sind, während Step einfach die Funktion ausführt. Also wenn man sein event hat, und hat jede Menge eigene Funktionen deklariert und ist sich sicher, daß diese korrekt sind, braucht man ja nur das Event. Da würde dann Step besser sein, weil mit Trace jedesmal die funktionen (die ja richtig sind) auch einzeln abgearbeitet werden.
Doof erklärt, iss aber so.

_________________
Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert