про Pascal

Dec 20, 2017 14:14

Программисты тут вроде водятся? :) Вот вам прикол на паскале. Проще некуда:

program zadacha1;
var x,y:real;
begin
x:=-1.0;
while x<=2 do
begin
y:=1;
    while y<=2 do
          begin
        writeln( x, '  ', y);
        y:=y+0.2;
    end;
  x:=x+0.2;
 end;
end.Запускаем. Смотрим (часть вывода опущена):

1.8  1.8
1.8  2
2  1
2  1.2
2  1.4
2  1.6
2 ( Read more... )

компьютерное

Leave a comment

Comments 9

kotm December 20 2017, 19:50:42 UTC
А попробуй перевести из real в int, а слагаемые умножить на 10, чтоб были целочисленные операции. Если проблема исчезнет, значит это особенности округления и сравнения чисел с плавающей запятой (не забываем про то, что в оригинале все операции в двоичной системе, где некоторые округления приводят к числам в периоде).

Интересно будет увидеть результат.

Reply

schukin December 20 2017, 20:03:35 UTC
Я, собственно, и сам почти уверен, что это - ошибка точности (округления). Но в обоих случаях - числа с плавающей точкой. Какая разница, +0.2 или +0.1? Кстати... в опущенной части вывода результата, где x=0, там вовсе не ноль, а что-то на десять в минус семнадцатой степени. Но в следующей итерации опять число с одной цифрой после запятой. Вокруг нуля возможны чудеса... но вокруг 2 как?

Reply

kotm December 20 2017, 20:07:30 UTC
Если выведешь число в полном его представлении, а не целочисленном, то можешь найти, на каком моменте происходит округление. Я на онлайн-эмуляторе получил вот это:

-2.0000000000000007E-001 1.7999999999999998E+000
-2.0000000000000007E-001 1.9999999999999998E+000
-6.6610670972078179E-017 1.0000000000000000E+000
-6.6610670972078179E-017 1.2000000000000000E+000
-6.6610670972078179E-017 1.3999999999999999E+000
-6.6610670972078179E-017 1.5999999999999999E+000
-6.6610670972078179E-017 1.7999999999999998E+000
-6.6610670972078179E-017 1.9999999999999998E+000
1.9999999999999993E-001 1.0000000000000000E+000
1.9999999999999993E-001 1.2000000000000000E+000

Reply

kotm December 20 2017, 20:10:00 UTC
Вроде как в паскале есть директива {$N-}, которая определяет программную или аппаратную работу с вещественными числами. Правда, либо я её неправильно использую, либо онлайн-эмуляторы её игнорируют.

Reply


anonymous December 23 2017, 09:21:47 UTC
Y меняется, быстрее того, как меняется X, а команда writeln( x, ' ', y); срабатывает после исполнения условия (Y<2). Как только Y достигает 2 (раньше, чем X достигает 2) печать прекращается.

Reply


Leave a comment

Up