Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Неправильный цикл


Автор: ACMilian 22.9.2006, 14:30
Объясните, пожалуйста, почему в цикле 
Код

 While v < v1 do
      begin
      New(i3);
      i3^.v := FloatToStr(v);
      i3^.hmm := IntToStr(hmm);
      GCalList.Add( i3 );
      v := v + hv;
      hmm := hmm + hhmm;
      end;

Первый раз от v до v1 оно пробегает правильно, а когда 
снова возвращается к этому циклу, то уже бежит не до <v1,
а до =v1?

Автор: TheCetus 22.9.2006, 14:43
покажи весь код

Автор: ACMilian 22.9.2006, 14:52
Код

 if s=d7 then
  begin
  Here:
  Readln( t, s );
  Here2:
  if s=d2 then
  begin
    CloseFile(t);
    AssignFile( t, fname );
    Reset(t);
    while not eof(t) do
    begin
      Readln(t,s);
      Readln(t,s);
      Here3:
      Readln(t,s);
      if s=d2 then
      begin
      New(i3);
      i3^.v := FloatToStr(v);
      i3^.hmm := IntToStr(hmm);
      GCalList.Add(i3);
      goto theend;
      end;
      begin
      hmm  := StrToInt(GetNextTerm( s )) * 10;
      v := StrToFloat(GetNextTerm( s ));
      Readln(t,s);
      if s=d2
      then
      begin
      New(i3);
      i3^.v := FloatToStr(v);
      i3^.hmm := IntToStr(hmm);
      GCalList.Add(i3);
      goto theend;
      end;
      hmm1 := StrToInt(GetNextTerm( s )) * 10;
      v1 := StrToFloat(GetNextTerm( s ));
      rv := v1-v;
      hv := rv / 10;
      rhmm := hmm1-hmm;
      hhmm := rhmm div 10;
      While v < v1 do
      begin
      New(i3);
      i3^.v := FloatToStr(v);
      i3^.hmm := IntToStr(hmm);
      GCalList.Add( i3 );
      v := v + hv;
      hmm := hmm + hhmm;
       end;
      goto here3;
      end;
    end;
  end;
  while not eof(t) do
   begin
   begin
    hmm  := StrToInt(GetNextTerm( s )) * 10;
    v := StrToFloat(GetNextTerm( s ));
    Readln(t,s);
    if s=d2
    then
    goto here2;
    hmm1 := StrToInt(GetNextTerm( s )) * 10;
    v1 := StrToFloat(GetNextTerm( s ));
    rv := v1-v;
    hv := rv / 10;
    rhmm := hmm1-hmm;
    hhmm := rhmm div 10;
    While v < v1 do
    begin
     New(i3);
     i3^.v := FloatToStr(v);
     i3^.hmm := IntToStr(hmm);
     GCalList.Add( i3 );
     v := v + hv;
     hmm := hmm + hhmm;
     end;
    goto Here;
   end;
  end;
 end;

Вот код...

Автор: Yanis 22.9.2006, 15:06
Цитата(ACMilian @  22.9.2006,  15:52 Найти цитируемый пост)
Вот код... 

smile
Жуть, а не код. Ты сам то в нём разбираешься?

Автор: ACMilian 22.9.2006, 15:12
Разбираюсь smile, ведь я его писал. 
Ну чего там может так глючить? Первый раз всё проходит правильно, а 
потом для цикла видите ли v(0.0123) не равно v1(0.0123) и цикл идёт ёще на один заход...

Автор: Romikgy 22.9.2006, 15:15
а дебагом не пробовал?

Автор: ACMilian 22.9.2006, 15:21
Извиняюсь, я новичок. А дебагом это как?, я пошагово смотрю.

Автор: Romikgy 22.9.2006, 15:29
Цитата(ACMilian @  22.9.2006,  14:21 Найти цитируемый пост)
я пошагово смотрю. 

и что видишь ?

Автор: ACMilian 22.9.2006, 15:41
То что в первый раз, когда v становится равным v1, цикл дальше не идёт,
потом переход на следующую строку. Снова приходим к этому циклу:
Код

 While v < v1 do
    begin
     New(i3);
     i3^.v := FloatToStr(v);
     i3^.hmm := IntToStr(hmm);
     GCalList.Add( i3 );
     v := v + hv;
     hmm := hmm + hhmm;
     end;

когда v становится равным v1...цикл пробегает ещё один раз и только на следующий раз, когда v уже больше v1 цикл прекращается.
Ничего не понимаю..

Автор: Romikgy 22.9.2006, 15:55
дык пошагово и посмотри что есть в переменых v & v1

Автор: ACMilian 22.9.2006, 16:05
Так я и говорю, что в них два одинаковых для человека числа 0.0123 и 0.0123(Навожу курсор при пошаговом)... Я читал если над числами производишь какие-то действия мат. операции, то для компа они уже будут чуточку различаться, надо что-то типа epsilon применять...может знаете как?

Автор: comtat 22.9.2006, 16:08
Цитата(ACMilian @  22.9.2006,  16:05 Найти цитируемый пост)
два одинаковых для человека числа 0.0123 и 0.0123

тогда
Код

While v < v1 do

и перестает выполняться 

Автор: Romikgy 22.9.2006, 16:09
Цитата(ACMilian @  22.9.2006,  15:05 Найти цитируемый пост)
epsilon

намного ниже чем 
Цитата(ACMilian @  22.9.2006,  15:05 Найти цитируемый пост)
0.0123

, и имхо эта трабла только в сравнении с нулем

Автор: ACMilian 22.9.2006, 16:16
Но вроде как epsilon можно самому описывать, типа const epsilon = 0.00001; или нет?

Автор: Romikgy 22.9.2006, 16:29
Цитата(ACMilian @  22.9.2006,  15:16 Найти цитируемый пост)
Но вроде как epsilon можно самому описывать, типа const epsilon = 0.00001; или нет? 

имхо ты от темы уходишь, создай еще одну тему и спроси можно ли менять эпсилон

Автор: drkot 22.9.2006, 16:54
ACMilian, у тебя эпсилон в пятом знаке, а при сравнении чисел ты приводиш до четвертого.
Возможно, что в хитросплетении твоего кода величина V теряет незначительную (но численно значащую) долю и при сравнении оказывается меньше V1.
Это возможно при вычислении шага (и причих операцияз связанных с делением).
Выбрость тело расчета, и проверь работу только цикла с приращением.

Автор: ACMilian 22.9.2006, 19:55
drkot  по-поводу epsilon, я его ещё не применял, а только поинтересовался как можно в моём случае использовать.
Всем спасибо. 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)