Преобразование типов иногда вызывает
легкий шок. Вычисляешь, например, расстояние между точками плоскости:
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 # 118034906