Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.07.31;
Скачать: CL | DM;

Вниз

Почему не завершается цикл?   Найти похожие ветки 

 
begin...end ©   (2003-07-18 15:26) [0]

Здравствуйте!

procedure TForm1.Button1Click(Sender: TObject);
const
Max = 1;
Step = 0.1;
var
I: Real;
begin
I := Max;
repeat
I := I - Step;
until I = Step;
Button1.Caption := FloatToStr(I);
end;


По идее, после 9 итераций цикл должен был закончиться, а он не заканчивается. Программа просто зависает. Почему так происходит? Если Step = 0.5, то цикл, как и положено, завершается при I = 0.5 после первой итерации.


 
Sandman25 ©   (2003-07-18 15:30) [1]

until I <= Step;

Вещественные числа не точно хранятся. Например, невозможно представить 0.1


 
Юрий Федоров ©   (2003-07-18 15:30) [2]

Сравниваешь два Real - так делать нельзя, они не сойдутся
Сравнивай их как Integer
round(I) = round(step)


 
Serginio   (2003-07-18 15:31) [3]

Потому, что i real.


 
begin...end ©   (2003-07-18 15:34) [4]

> Sandman25 © (18.07.03 15:30)

> Вещественные числа не точно хранятся. Например, невозможно представить 0.1

Тогда всё равно интересно, почему в случае 0,5 всё нормально работает.

> until I <= Step;

Но ведь может получиться, например, I = 0.100000001, и тогда будет произведён лишний проход цикла. Или я ошибаюсь?


 
Verg ©   (2003-07-18 15:35) [5]

Советую почитать про предсталение вещественных чисел в двоичной системе. Ключь - имеет ли число 0.1 точное представление в указанной системе счисления?


 
Юрий Федоров ©   (2003-07-18 15:35) [6]

Пардон, фигню написал насчет round.
Пятница, жара...


 
Skier ©   (2003-07-18 15:35) [7]

>begin...end © (18.07.03 15:34)

> Тогда всё равно интересно, почему в случае 0,5 всё нормально
> работает.

Потому что конечная десятичная дробь не всегда является конечной
двоичной...


 
Verg ©   (2003-07-18 15:40) [8]

0.5 => в двоичной системе - это число 0.1 - абсолютно точно (погрешность =0).

В обще случае надо сравнивать так
abs(I-Step)>Epsilon, где epsilon - погрешность, которая тебя устраивает, но не менее той, котороя обеспечивается разрядностью хранимых переменных.


 
Serginio   (2003-07-18 15:44) [9]

0.5=2^-1;


 
begin...end ©   (2003-07-18 15:47) [10]

Так-так... Я, кстати, тоже предполагал, что причина - во внутреннем представлении вещественных чисел (правда, было непонятно про 0.5, но сейчас дошло, спасибо Verg и Skier).

> Verg © (18.07.03 15:40)
То есть, если я использую, например, тип Extended, то Epsilon не может быть меньше, чем 1Е-19 (вроде бы, Extended обеспечивает именно такую точность). Так?


 
Skier ©   (2003-07-18 15:59) [11]

I - Step; // The value of x/y is of type Extended, regardless of the types of x and y. For other arithmetic operators, the result is of type Extended whenever at least one operand is a real
I: Real; = I: Double;



 
Verg ©   (2003-07-18 16:01) [12]


> То есть, если я использую, например, тип Extended, то Epsilon
> не может быть меньше, чем 1Е-19 (вроде бы, Extended обеспечивает
> именно такую точность). Так?


Насчет -19 (может -190) не помню, но принцип таков, да.

Цикл по переменной вещественного типа толжен быть ограничен минимальным допустимым приближением (расстоянием) этой переменной к пределу цикла или преодолением (больше-меньше) предела, но никак не точным равенством этому пределу.


 
Serginio   (2003-07-18 16:04) [13]

Погрешность для чисел не абсолютная а относительная величина.
Для Extended около 20 значимых десятичных разрядов.
Кроме всего прочего когда объявляешь константу то неизвестно к какому типу приведет ее компилятор. Double<>Currency;
А погрешность нужно рассчитывать из количества предполагаемых вычислений входе которых появляюется погрешность и учитывать абсолютные значения переменных.


 
begin...end ©   (2003-07-18 16:04) [14]

Понятно. Всем большое спасибо.


 
Skier ©   (2003-07-18 16:17) [15]

>begin...end © (18.07.03 16:04)
http://www.delphikingdom.ru/helloworld/reals.htm


 
begin...end ©   (2003-07-18 16:27) [16]

> Skier © (18.07.03 16:17)

> http://www.delphikingdom.ru/helloworld/reals.htm

Ого! Вам - отдельное спасибо.



Страницы: 1 вся ветка

Текущий архив: 2003.07.31;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.013 c
14-100903
BAYES
2003-07-14 11:52
2003.07.31
БИБЛИОТЕКА EhLib3.1


14-100884
mikhasenko.anton
2003-07-16 08:25
2003.07.31
Где найти компонент DBF?


3-100540
inspirion
2003-07-11 00:01
2003.07.31
Медиа файлы и БД


1-100806
Yuraz
2003-07-17 09:31
2003.07.31
Как узнать полный путь запущенной программы?


3-100573
Zelius
2003-07-04 10:06
2003.07.31
Проблемы с запросами из-под FastReport