Pascal文件\控制台输出

时间:2015-05-26 19:57:26

标签: output pascal

我写了一个程序来计算不同精度的方程根。 4种不同的方法。 我使用PascalABC。

所以,问题是:当我想看输出时,程序只显示4个方法的结果。订单不会影响输出结果,也不会影响文件\控制台输出。 我完全不知道该怎么做,这是我第一次遇到这个问题。至少在Pascal。 这是代码:

 uses crt;

type 
pint = ^integer;
aptr = ^real;
bptr = ^real;
xpreal = array[1..6] of real;
npint = array[1..6] of integer;

function fun(x:real): real; 
begin fun := x * x * x + x * x - 3; end;

function dfdx(x:real): real; 
begin dfdx := 3 * x * x + 2 * x end;

function fi(x:real): real; 
begin fi := sqrt(3 / (x + 1)) end;

function half(a, b, eps:real; n:pint):real;
var
    x:real;
begin
  n^ := 0;
    repeat
    x := (a + b) / 2;
    n^ := n^ + 1;
    if (fun(a) * fun(x) >= 0) then
        a := x
    else
        b := x; 
    until abs(fun(x)) < eps;
    half := x;
end;

function def(b, eps:real; n:pint):real;
var
    x: real;
begin
    x := b;
    n^ := 0;
    repeat 
     x := x - fun(x) / dfdx(x);
     n^ := n^ + 1;
    until abs(fun(x)) < eps;
    def := x;
end;

function itr(a: aptr; b: bptr): real;
var
 x: real;  
begin
 x := fun(a^) * (a^-b^) / (fun(b^) - fun(a^)) + a^;
   if fun(x) * fun(a^) >= 0 then a^ := x else a^ := a^;
   if fun(x) * fun(b^) >= 0 then b^ := x else b^ := b^;
 itr := x;
end;

function hord(a, b, eps:real; n:pint):real;
begin
    n^ := 0;
 while(abs(fun(itr(@a, @b))) > eps) do 
   begin  
     n^ := n^ + 1; 
   end;
 hord := itr(@a, @b);
end;

function iter(b, eps:real; n:pint):real;
var
    x: real;
begin
  n^ := 0;
    x := b;
    repeat 
    x := fi(x);
    n^ := n^ + 1;
    until abs(fun(x)) < eps;
    iter := x;
end;

procedure graph(var inf: text; x:xpreal; n: npint; c: integer);
var
 i,j:integer;
 eps: real;
begin
  eps := 0.01;
  writeln(inf); 

  write(inf, 'eps= ');
  for i := 1 to c do
    begin
      write(inf, eps:6:7, '   ');
      eps := eps * 0.1;
    end;

  writeln(inf);  write(inf, 'x  = ');
  for i := 1 to c do
     begin
       write(inf, x[i]:8:7,'   ');
     end;
  writeln(inf);  writeln(inf); 
  writeln(inf, '^N'); writeln(inf); 

  for i := n[c-1] downto 0 do
    begin
   writeln(inf, '|');
    for j := 1 to c do
        if (n[j] = i) then
            write(inf, '<*>')
        else write(inf, '    ');
   writeln(inf); 
    end;

 writeln(inf, '+------------------------------------> eps');
 writeln(inf); 

  eps := 0.01;
  for i := 1 to 6 do
    begin
       write(inf, 'EPS = : ', eps:6:7);
   for j := 0 to n[i] do
    write(inf,'* ');
  write(inf,n[i]);
  writeln(inf); 
  eps := eps * 0.1;
    end;
 writeln(inf, '__________________________');
end;

var 
  a, b, eps : real;
  i         : integer;
  x         : xpreal;
  n         : npint;
  inf       : text;

begin
    a := 0.6;
    b := 1.4;
    eps := 0.01;

    assign(inf,'C:\My Documents\Pas\output.txt');
    rewrite(inf);

    for i := 1 to 6 do //1-st output
        begin
        x[i] := half(a, b, eps, @n[i]);
        eps := eps * 0.1;
        end;
    writeln(inf, 'half-seg-method');
    graph(inf, x, n, 6); 

    for i := 1 to 6 do //2-nd output
        begin
        x[i] := def(b, eps, @n[i]);
        eps := eps * 0.1;
        end;
    writeln(inf, 'Newton-method');
    graph(inf, x, n, 6); 

  for i := 1 to 6 do //3-rd output
        begin
        x[i] := iter(b, eps, @n[i]);
        eps := eps * 0.1;
        end;
    writeln(inf, 'iter-method');
    graph(inf, x, n, 6); 

    for i := 1 to 6 do //4-th output 
        begin
        x[i] := hord(a, b, eps, @n[i]);
        eps := eps * 0.1;
        end;
    writeln(inf, 'hord-method');
    graph(inf, x, n, 6); 

        close(inf);
end.

1 个答案:

答案 0 :(得分:0)

您的代码存在很多问题:

首先:主要的错误是由于编码你想要不可能的精度 错误。您忘记在每次循环之前将eps重置为0.01,因此您使用eps=1e-8启动六个牛顿部分并将其结束 与eps=1e-14

  eps := 0.01;
  for i := 1 to 6 do {3-rd output}
        begin
        x[i] := iter(b, eps, @n[i]);
        eps := eps * 0.1;
        end;
    writeln(inf, 'iter-method');
    graph(inf, x, n, 6);

  eps := 0.01;
  for i := 1 to 6 do {4-th output}
  ....

第二个问题是您的收敛测试可能会因绝对错误标准而失败。通常我们使用相对错误测试,例如为你的牛顿:

function def(b, eps:real; n:pint):real;
var
    x: real;
    d: real;
begin
    x := b;
    n^ := 0;
    repeat
     d := fun(x) / dfdx(x);
     x := x - d;
     n^ := n^ + 1;
    until abs(d) < eps*abs(x);
    def := x;
end;

这另外显示了编码风格的另一个问题。您可以使用相同的参数反复评估函数,而不是将函数值存储在局部变量中:对于简单函数来说,这可能几乎没有问题,但是对于更复杂的函数来说非常昂贵且无效。 在你的function itr(a: aptr; b: bptr): real;而不是三个函数调用中,你做的更强烈

...