Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2003.07.31;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.47 MB
Время: 0.009 c
1-100721
Дома
2003-07-18 16:54
2003.07.31
GetCaretPos из user32.dll


1-100775
mox
2003-07-16 22:11
2003.07.31
Edit или Memo др. приложения


1-100744
_Санек_
2003-07-16 10:12
2003.07.31
Как передать в параметр процедуры массив?


4-101026
dimonf
2003-05-28 11:02
2003.07.31
Подскажите какая функция в API отвечает за вывод PopupMenu???


3-100555
PlaTinum
2003-07-07 22:25
2003.07.31
SQL





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский