2013-11-16 2 views
2

это мой список:Почему этот алгоритм деления пополам не завершен?

procedure TForm1.Button1Click(Sender: TObject); 
var 
    i: Integer; 
    x1, x2, x3, xl, xr, xm, hasil, hasil2: Real; 
begin 
    xl := StrToFloat(Edit1.Text); 
    xr := StrToFloat(Edit2.Text); 
    x1 := F1(xl); 
    x2 := F1(xr); 
    hasil := x1 * x2; 
    if hasil > 0 then 
    begin 
    ShowMessage('Try Again....!!!'); 
    Edit1.Clear; 
    Edit2.Clear; 
    end 
    else 
    begin 
    i := 1; 
    repeat 
     xm := (xl + xr)/2; 
     x3 := F1(xm); 
     hasil2 := x1 * x3; 
     if hasil2 < 0 then 
     begin 
     xr := xm; 
     x2 := x3; 
     end 
     else 
     begin 
     xl := xm; 
     x1 := x3; 
     end; 
     ListBox1.Items.Add(FloatToStr(xm)); 
     i := i + 1; 
    until 
     x3 = 0; 
    end; 
end; 

листинга около Bisection МЕТОДЫ .... проблемы является ..... почему цикл не остановить ...

кто может помочь me ... please

+1

Причина в том, что 'x3' никогда не становится равным нулю. Возможно, вы могли бы попробовать вместо IsSero (x3) 'или' Abs (x3)

+0

... или вы можете остановиться после шагов «N» (например, 1 000 000), если только вы не достигнете некоторого эпсилона. –

+0

Редкий любой момент, выполняющий более 50 итераций пополам –

ответ

6

Конечная точность арифметики с плавающей запятой на компьютере неточна. Не все числа могут быть представлены точно и, следовательно, арифметика на компьютере связана с приближением. Возможно, ваша функция не имеет точного решения на компьютере. Или, возможно, решение существует, но аппроксимация означает, что его невозможно найти.

Вместо проверки на равенство с нулем проверьте, что ваше значение близко к нулю.

until abs(x3) < 1.0e-6; 

, где допущение должно быть выбрано в соответствии с некоторыми аргументированными аргументами, основанными на проблеме.

Другим разумным критерием остановки для деления пополам является то, что xl и xr становятся очень близкими. То, какой подход лучше всего подходит для вас, зависит от функции, которую вы решаете, и от свойств, которые вы требуете от этого решения.

Такие проблемы деликатные. Если вы используете допуск, вы можете выбрать его слишком низко. И тогда ваша петля не закончится, привычная ситуация. Поэтому вы должны всегда пытаться выручить после некоторого большого количества итераций. Если вы не сможете точно убедиться, что цикл, безусловно, завершится.


Некоторые рекомендации по отладке. Вы уже знали, что цикл не заканчивается. Таким образом, x3 никогда не достигал нуля. В этот момент вы могли бы выполнить некоторую отладку и проверить значения x3, а также другие переменные. Если бы вы это сделали, я уверен, что вы поняли бы проблему самостоятельно. Изучение того, как отлаживать проблемы, является критически важным навыком.

+0

Да, но отладка может привести к пробным ошибкам ;-) – JensG

+0

@JensG Я цитирую: «... где толерантность должна быть выбрана в соответствии с некоторыми аргументированными аргументами, основанными на проблеме." –

+0

@ user2467583 Вам нужна помощь? –