Помощь - Поиск - Пользователи - Календарь
Полная версия: Проблема с определением целочисленности
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
looogle
Доброго времени суток!

При написании программы возникла непонятная проблема.


var
f: text;
l, a, b, r: real;
i: integer;
k: byte;

begin
Assign(f, 'input.txt');
Reset(f);
Readln(f, l);
Readln(f, a);
Readln(f, b);
close(f);

r := a;
k := 0;

for i := 1 to round(l / a) do
begin
if (r / b = round(r / b)) then inc(k);
r := r + a;
writeln(r, ' - ',r / b:10:10,' = ', round(r / b),' - ',r / b = round(r / b));
end;

Assign(f, 'output.txt');
Rewrite(f);
write(f, k);
close(f);

end.



Начальные значения:


l = 10.5
a = 1.005
b = 0.004



Результаты:
Изображение

На картинке видно, что почему-то при верном равенстве на результат выводит fasle.

В чём проблема?

Заранее спасибо.
IUnknown
Цитата
В чём проблема?
В погрешности представления вещественных чисел. Нельзя сравнивать вещественное число ни с другим вещественным (ни тем более с целым) оператором "=", можно только смотреть, насколько одно отличается от другого, и если модуль разности не превышает какого-то граничного значения - то считать числа равными.

Цитата
На картинке видно, что почему-то при верном равенстве
На картинке - это результат вывода. Вывод происходит с округлением. Посмотри в отладчике, чему равны значения r/b перед выполнением WriteLn, тогда продолжим разговор.
looogle
Результаты деления в данном случае равны:
4,02 / 0,004 = 1005
8,10 / 0,004 = 2010

Посчитал вручную. Всё должно получатся, по-моему.

Однако, при выводе
frac(r/b);

получаю бесконечную десятичную дробь, соответственно 0.999999999999886 и 0.999999999999773

dry.gif
IUnknown
Турбо-Паскаль, при отключенном сопроцессоре (режим {$N-}):

 2.0100000000E+00 -      502.50000000000 = 503 - FALSE
3.0150000000E+00 - 753.75000000000 = 754 - FALSE
4.0200000000E+00 - 1005.00000000000 = 1005 - TRUE
2.0100000000E+00 - 502.50000000000 = 503 - FALSE
3.0150000000E+00 - 753.75000000000 = 754 - FALSE
4.0200000000E+00 - 1005.00000000000 = 1005 - TRUE
5.0250000000E+00 - 1256.25000000000 = 1256 - FALSE
6.0300000000E+00 - 1507.50000000000 = 1507 - FALSE
7.0350000000E+00 - 1758.75000000000 = 1759 - FALSE
8.0400000000E+00 - 2010.00000000000 = 2010 - TRUE
9.0450000000E+00 - 2261.25000000000 = 2261 - FALSE
1.0050000000E+01 - 2512.50000000000 = 2513 - FALSE
1.1055000000E+01 - 2763.75000000000 = 2764 - FALSE

looogle
Хммм.. Странно. В Pascal ABC по другому. И отключённый сопроцессор не помогает. Попробую Free Pascal.

Возможно ещё как нибудь проверить целочисленность чисел?

unsure.gif
IUnknown
FPC выдает те же результаты, что приведены в первом посте, отключить сопроцессор там нельзя.
looogle
А как на счёт другого случая? Как ещё можно проверить целое ли число?
IUnknown
Uses Math;
Var l, a, b, r: Extended;
// ...
writeln(..., SameValue(r/b, trunc(r/b)));
(FPC)
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.