Главная | Каталог ресурсов | Специальная рубрика | Глюки | Задать вопрос | Форум | Чат | О создателе
Глюки!
Глюки

Преобразование типов иногда вызывает легкий шок. Вычисляешь, например, расстояние между точками плоскости:

var x1,y1,x2,y2,dx,dy:integer;d:real;
begin
  x2:=520;y2:=200;
  x1:=320;y1:=200;
  dx:=x2-x1;
  dy:=y2-y1;
  d:=dx*dx+dy*dy;{???}
  d:=sqrt(d);{!!!}
end.
, а он не хочет извлекать корень!!!

      Ошибка при вычислении возникает из-за того, что промежуточная переменная при вычислении выражения {???} берётся того же типа, что и операнды, т.е.INTEGER, и вычисления производятся с отбрасыванием старших разрядов, что и приводит к появлению отрицательного знака.

      Попробуйте выполнить эту программу, установив точки останова на строках {!!!}. Вы с удивлением обнаружите, что остановки происходят не всегда, хотя переменные примают эти значения (можете установить курсор на строку y:=0; , нажимать <F4> и смотреть в окне Watches !!!)

var x,y:real;
begin
  x:=0;
  repeat
    y:=0;
    repeat
      if (x=0.5)and(y=0.5)
        then
          begin
            writeln(x:1:1,' ',y:1:1);{!!!}{1}
          end;
      if (x=1)and(y=0)
        then
          begin
            writeln(x:1:1,' ',y:1:1);{!!!}{2}
          end;
      y:=y+0.1;
    until y>2;
    x:=x+0.1;
  until x>2;
end.

      Несмотря на все ВАШИ старания остановки в точке {2} не происходит. Это объясняется тем, что при действиях с числами вещественого типа вычисления происходят приблизительно с точностью до 12 знака после первой значащей цифры.

      В документации фирмы Borland процедура Val описана так:

procedure Val(S; var V; var Code: Integer);

где:

S
переменная строкового типа; должна быть последавательностью символов, формирующей число;
V
переменная целого или вещественного типа;
Code
переменная типа Integer.

      Так же сказано, что переменная Code содержит номер первого ошибочного символа. Но в случае, подобном Val('1E+E',V,Code); значение переменной Code станет равно не 2, как кажется, а 4, т.е. ошибочно не присутствие 'E+' после 1, а отсутствие показателя в экспоненциальной форме записи числа.

      Трассировка при отладке, что может быть проще! Нажимаешь <F7> и смотришь все операторы по ходу выполнения. И в прочедуры с функциями заглядываешь. Это так, но не всегда. В приведённой ниже программе достаточно нажать <F7> 2 раза и она выполнитя вся.

procedure mainproc;procedure pr1;begin end;begin
  writeln('А нету трассировки!!!');
  writeln('Посмотри по <Alt-F5>!!!');
  writeln('Думай, почему!!!');
end;
begin mainproc;
end.

      В программе важно расположение по строкам, т.к. именно положение begin для процедуры mainproc на одной строке с дополнительной процедурой pr1 и даёт такой результат (В браузере ВЫ можете увидеть искаженную автоматическим переносом программу; просто скопируйте её в блокнот, положение с переносом исправится).

Назад
Дизайн и поддержка сайта - Старынин Валерий. E-mail staryx@inbox.ru Статус ICQ ICQ # 118034906
Hosted by uCoz