Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Центр помощи > Посчитать сумму бесконечного ряда


Автор: AL 4.12.2005, 03:01
arctan(x) = x - x^3/3 +x^5/5 - x^7/7 + ... (-1)^n * x^(2n+1)/(2n+1) ; верно при |x| <= 1

Задачку делаю в визуальном режиме. Delphi. Заданная точность 0.0001. вот код функции:

Код

  function CalcRow(X: Extended): Extended;
    var
      Y, Eps, S: Extended;
      m: SmallInt;
      n: Word;
    begin
      n := 1;
      S := X;
      Eps := 0.0001;
      while Abs(Y) > Eps do
        begin
          if (Odd(n) and (X>0)) or ((X mod 2 = 0) and (X<0)) then m:=-1
          else m:=1;
          Y := m*Exp((2*n+1) * Ln(Abs(X)))/(2*n+1);
          S := S + Y;
          Inc(n);
        end;
      Result := S;
    end;


Даже не запускается. Тут ещё фишка в том, что невозможно возводить отрицательное число в степень с помощью логрифма(именно поэтому там такое условие и переменная m и взят модуль)... Вообщем запутался я - помогите плз.

Автор: AL 4.12.2005, 03:03
Там в 12 строке: n mod 2 - поправлял тут...

Автор: Mal Hack 4.12.2005, 04:17
Код
program sr;

{$APPTYPE CONSOLE}

uses
  SysUtils , Math;

var
 x , x0 , y , s , a , b , eps , r , sn , err : extended;
 z , n , i , st , j : integer;

begin

 write( 'Enter EPS: ' ); readln( eps );
 write( 'Enter X: ' ); readln( x0 );
 write( 'Enter N: ' ); readln( n );
 write( 'Enter J (ogranichenie iteraciy): ' ); readln( j );
{
 eps := 0.01;
 x0 := 2;
 n := 20;
}
 writeln;

 y := ln( x0 + sqrt( 1 + sqr( x0 ) ) );

 writeln( 'Y = ' , y : 8 : 4 , '   Formula: ln( x + ( 1 + x^2 ) ^ 1 / 2 ).' );

 writeln;

 z := 1;
 i := 2;
 a := 1;
 b := 1;
 r := x0;

 while ( abs( r ) > eps ) AND ( i - 1 < j ) do
  begin
   s := s + r;

   if i < n then
    sn := sn + r;

   st := 2 * i - 1;

   a := a * ( st - 2 );
   b := b * ( st - 1 );
   x := IntPower( x0 , st );

   z := z * ( -1 );

   r := z * a * x / b / st;
   Inc( i );
  end;

 if abs( r ) > eps then
  writeln( 'Tochnost'' ne dostignuta za ' , j , ' iteraciy.' );

 writeln( 'S := ' , s : 9 : 5 , ' pri EPS = ' , eps : 8 : 5 );
 writeln( 'S(' , n , ') := ' , sn : 9 : 5 );

 err := abs( ( y - s ) / y * 100 );

 writeln( 'Pogreshnost = ' , err : 8 : 2 , '%' );

 readln;
end.

Автор: AL 4.12.2005, 12:55
Что-то у Вас код какой-то совсем неправильный. Начиная от того, что по условию |x| < 1 да и ответ выдаёт при x=1 около 0,88 - а должно быть 0,78... Раскаладывал это как многочлен по Горнеру - там разница на 3 знаке(0,785 и 0,783).

smile

Автор: AL 4.12.2005, 13:03
Ура! Заработало:

Код

  function CalcRow(X: Extended): Extended;
    var
      Y, Eps, S: Extended;
      m: SmallInt;
      n: Word;
    begin
      n := 1;
      S := 0;
      Eps := 0.0001;
      Y := X;
      while Abs(Y) > Eps do
        begin
          S := S + Y;
          if (Odd(n) and (X>0)) or ((n mod 2 = 0) and (X<0)) then m:=-1
          else m:=1;
          Y := m*Exp((2*n+1) * Ln(Abs(X)))/(2*n+1);
          Inc(n);
        end;
      Result := S;
    end;


Разница с формулой - на 5 знаке =) Всем спасибо.

Автор: AL 4.12.2005, 13:12
Ещё один вопрос кстати. У меня есть поле(Edit) - я туда ввожу число(X), нажимаю кнопку OK.
А ниже ещё 3 поля Edit, так вот в них ответы появляются только после того как я кликну на 1 из них, а хотелось бы сразу после нажатия Ok.

Автор: AL 4.12.2005, 13:25
Естественно стояло onclick на поле, а не кнопку) Разобрался.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)