Форум: "Основная";
Текущий архив: 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