Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

[Turbo Pascal] вычисление sin, cos и квад-го корня из действительного числа

7.4K
17 января 2007 года
Nook
65 / / 17.01.2007
Помогите пожалуйста написать программу, содержащую процедуры вычисления синуса, косинуса и квадратного корня из действительного числа.

p.s. плиZZ
63
17 января 2007 года
Zorkus
2.6K / / 04.11.2006
Переводи число в целое, потому что с ним проще работать. А затем используй разложения Тейлора для трансиендентных функций. Матан рулит:) А потом обратно его в дробное.
622
17 января 2007 года
nilbog
507 / / 19.12.2006
sin(x)=x-x^3/3! + x^5/5! -...+x^(n-1/2)/n!
cos(x)=1-x^2/2!+x^4/4!-.....+x^(n/2)/n!
ну а вычисляешь с требуемой точно eps
пока очередной член не будет меньше eps
7.4K
18 января 2007 года
Nook
65 / / 17.01.2007
Если не сложно то напиши пожалуйста сам текст программы а то я вообще не шарю в TP 7.0.
плиZZ
271
18 января 2007 года
MrXaK
721 / / 31.12.2002
портированный алгоритм (из си) из FreeBSD (k_sin.c)
Код:
program a;
var
 half, s1, s2, s3, s4, s5, s6 : real;

{/* __kernel_sin( x, y, iy)
 * kernel sin function on ~[-pi/4, pi/4] (except on -0), pi/4 ~ 0.7854
 * Input x is assumed to be bounded by ~pi/4 in magnitude.
 * Input y is the tail of x.
 * Input iy indicates whether y is 0. (if iy=0, y assume to be 0).
 *
 * Algorithm
 *  1. Since sin(-x) = -sin(x), we need only to consider positive x.
 *  2. Callers must return sin(-0) = -0 without calling here since our
 *     odd polynomial is not evaluated in a way that preserves -0.
 *     Callers may do the optimization sin(x) ~ x for tiny x.
 *  3. sin(x) is approximated by a polynomial of degree 13 on
 *     [0,pi/4]
 *                   3            13
 *      sin(x) ~ x + S1*x + ... + S6*x
 *     where
 * 
 *  |sin(x)         2     4     6     8     10     12  |     -58
 *  |----- - (1+S1*x +S2*x +S3*x +S4*x +S5*x  +S6*x   )| <= 2
 *  |  x                               |
 *
 *  4. sin(x+y) = sin(x) + sin'(x')*y
 *          ~ sin(x) + (1-x*x/2)*y
 *     For better accuracy, let
 *           3      2      2      2      2
 *      r = x *(S2+x *(S3+x *(S4+x *(S5+x *S6))))
 *     then                   3    2
 *      sin(x) = x + (S1*x + (x *(r-y/2)+y))
 */
}
function sin(x, y : real; iy : integer) : real;
var
z, r, v : real;
begin
  z := x*x;
  v := z * x;
  r := s2+z*(s3+z*(s4+z*(s5+z*s6)));
  if( iy = 0 ) then begin
    sin := x+v*(s1+z*r);
  end
  else
  begin
    sin := x-((z*(half*y-v*r)-y)-v*s1);
  end;

end;


begin
  half :=  5.00000000000000000000e-01, { 0x3FE00000, 0x00000000 }
  S1  := -1.66666666666666324348e-01, { 0xBFC55555, 0x55555549 }
  S2  :=  8.33333333332248946124e-03, { 0x3F811111, 0x1110F8A6 }
  S3  := -1.98412698298579493134e-04, { 0xBF2A01A0, 0x19C161D5 }
  S4  :=  2.75573137070700676789e-06, { 0x3EC71DE3, 0x57B1FE7D }
  S5  := -2.50507602534068634195e-08, { 0xBE5AE5E6, 0x8A2B9CEB }
  S6  ;=  1.58969099521155010221e-10; { 0x3DE5D93A, 0x5ACFD57C }

end.


аналогично косинус:
Код:
one :=  1.00000000000000000000e+00, { 0x3FF00000, 0x00000000 }
C1  :=  4.16666666666666019037e-02, { 0x3FA55555, 0x5555554C }
C2  := -1.38888888888741095749e-03, { 0xBF56C16C, 0x16C15177 }
C3  :=  2.48015872894767294178e-05, { 0x3EFA01A0, 0x19CB1590 }
C4  := -2.75573143513906633035e-07, { 0xBE927E4F, 0x809C52AD }
C5  :=  2.08757232129817482790e-09, { 0x3E21EE9E, 0xBDB4B1C4 }
C6  := -1.13596475577881948265e-11; { 0xBDA8FAE9, 0xBE8838D4 }

{/*
 * __kernel_cos( x,  y )
 * kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164
 * Input x is assumed to be bounded by ~pi/4 in magnitude.
 * Input y is the tail of x.
 *
 * Algorithm
 *  1. Since cos(-x) = cos(x), we need only to consider positive x.
 *  2. if x < 2^-27 (hx<0x3e400000 0), return 1 with inexact if x!=0.
 *  3. cos(x) is approximated by a polynomial of degree 14 on
 *     [0,pi/4]
 *                           4            14
 *      cos(x) ~ 1 - x*x/2 + C1*x + ... + C6*x
 *     where the remez error is
 * 
 *  |              2     4     6     8     10    12     14 |     -58
 *  |cos(x)-(1-.5*x +C1*x +C2*x +C3*x +C4*x +C5*x  +C6*x  )| <= 2
 *  |                                      |
 *
 *                 4     6     8     10    12     14
 *  4. let r = C1*x +C2*x +C3*x +C4*x +C5*x  +C6*x  , then
 *         cos(x) ~ 1 - x*x/2 + r
 *     since cos(x+y) ~ cos(x) - sin(x)*y
 *            ~ cos(x) - x*y,
 *     a correction term is necessary in cos(x) and hence
 *      cos(x+y) = 1 - (x*x/2 - (r - x*y))
 *     For better accuracy, rearrange to
 *      cos(x+y) ~ w + (tmp + (r-x*y))
 *     where w = 1 - x*x/2 and tmp is a tiny correction term
 *     (1 - x*x/2 == w + tmp exactly in infinite precision).
 *     The exactness of w + tmp in infinite precision depends on w
 *     and tmp having the same precision as x.  If they have extra
 *     precision due to compiler bugs, then the extra precision is
 *     only good provided it is retained in all terms of the final
 *     expression for cos().  Retention happens in all cases tested
 *     under FreeBSD, so don't pessimize things by forcibly clipping
 *     any extra precision in w.
 */
}

function cos(x, y : real) : real;
var
hz, z, r, w : real;
begin
    z  := x*x;
    r  := z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*C6)))));
    hz := (float)0.5*z;
    w  := one-hz;
    cos := w + (((one-w)-hz) + (z*r-x*y));
  end;

end;


з.ы. запускать не пробовал))) но должно работать если с синтаксисом нигде не навалял
271
18 января 2007 года
MrXaK
721 / / 31.12.2002
вот корень... тоже портирован с си, но не из стандартной либы
Код:
function Sqroot1( x: real) : real;
var
  sp,i,inv : integer;
  a,b : real;
begin
  sp := 0;
  inv := 0;
  if(x<=0.F) then
    Sqroot := 0.F;
  { argument less than 1 : invert it }
  if(x<1.F) then
  begin
    x:=1.F/x;inv:=1;
  end;
  { process series of division by 16 until argument is <16 }
  while(x>16.F) do begin
    sp := sp + 1;
    x := x / 16.F;
  end;
  { initial approximation }
  a:=2.F;
  { Newtonian algorithm }
  for i := ITNUM downto 1 do
  begin
    b:=x/a;
    a := a+b;
    a:=a*0.5F;
  end;
  { multiply result by 4 : as much times as divisions by 16 took place }
  while(sp>0)  do begin
    sp--;
    a:=a*4.F;
  end;
  { invert result for inverted argument }
  if(inv) then
    a:=1.F/a;
  Sqroot1 := a;
end;

опять же не компилил) но должно работать
7.4K
18 января 2007 года
Nook
65 / / 17.01.2007
Спасибо за помощь . Работает !!!!!!!!! Круто
271
18 января 2007 года
MrXaK
721 / / 31.12.2002
реально работает?) ща посмотрел - заметил ошибку))
там где корень)
вместо
 
Код:
sp--;

 
Код:
sp := sp - 1;
552
18 января 2007 года
Ivanhoe
373 / / 30.04.2006
Не понял, в чем трабл?

 
Код:
Sin(x);
  Cos(x);
  Sqrt(x);
325
19 января 2007 года
Franky
723 / / 10.08.2005
да, я тоже не взялся за решение этой задачки, т.к. не понял почему нельзя использовать просто sin, cos...
242
19 января 2007 года
Оlga
2.2K / / 04.02.2006
Цитата:
...написать программу, [COLOR=red]содержащую процедуры вычисления[/COLOR] синуса, косинуса и квадратного корня...


просто задание дали человеку такое. это довольно частое явление, что студентам задают реализовывать функции/процедуры, которые есть в стандартных библиотеках.

325
19 января 2007 года
Franky
723 / / 10.08.2005
судя по уровню других его задач там надо было что-то вроде:
 
Код:
function sin_(r:real):real;
begin
sin(r);
sin_:=r;
return r;
end;
271
19 января 2007 года
MrXaK
721 / / 31.12.2002
а в паскале есть return разве? ))

зато потренировался с си на паскаль портировать)) и в ядре bsd покопался))
325
19 января 2007 года
Franky
723 / / 10.08.2005
фу, блин! Ты прав :)
Вредно мешать Пасцаль с ЯваСкр... ик! %)
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог