为什么这个二分算法无法终止?

use*_*583 2 delphi pascal delphi-2010

这是我的上市:

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;
Run Code Online (Sandbox Code Playgroud)

列表是关于BISECTION METHOD ....问题是.....为什么循环没有停止...

任何人都可以帮助我......拜托

Dav*_*nan 6

计算机上的有限精度浮点运算是不精确的.并非所有数字都可以准确表示,因此计算机上的算术涉及近似值.因此,您的功能可能在计算机上没有确切的解决方案.或许解决方案存在,但近似意味着无法找到它.

而不是测试零等于,测试您的值接近于零.

until abs(x3) < 1.0e-6;
Run Code Online (Sandbox Code Playgroud)

必须根据基于手头问题的一些合理论证来选择容差.

二分的另一个明智的停止标准是xl和xr变得非常接近.究竟什么方法最适合您取决于您​​要解决的功能,以及您需要该解决方案的属性.

这些问题很微妙.如果使用公差,则可能选择它太低.然后你的循环不会终止,这是一个熟悉的情况.因此,在经过大量迭代后,您应该总是试图挽救.除非你能确定循环肯定会终止.


关于调试的一些建议.你已经知道循环没有终止.很明显x3并没有达到零.此时您可以完成一些调试并检查x3的值以及其他变量.如果你这样做了,我相信你会自己理解这个问题.学习如何调试问题是一项至关重要的技能.