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.
[Turbo Pascal] вычисление sin, cos и квад-го корня из действительного числа
p.s. плиZZ
Переводи число в целое, потому что с ним проще работать. А затем используй разложения Тейлора для трансиендентных функций. Матан рулит:) А потом обратно его в дробное.
cos(x)=1-x^2/2!+x^4/4!-.....+x^(n/2)/n!
ну а вычисляешь с требуемой точно eps
пока очередной член не будет меньше eps
плиZZ
Код:
аналогично косинус:
Код:
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;
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;
з.ы. запускать не пробовал))) но должно работать если с синтаксисом нигде не навалял
Код:
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;
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;
опять же не компилил) но должно работать
Спасибо за помощь . Работает !!!!!!!!! Круто
там где корень)
вместо
Код:
sp--;
Код:
sp := sp - 1;
Код:
Sin(x);
Cos(x);
Sqrt(x);
Cos(x);
Sqrt(x);
да, я тоже не взялся за решение этой задачки, т.к. не понял почему нельзя использовать просто sin, cos...
Цитата:
...написать программу, [COLOR=red]содержащую процедуры вычисления[/COLOR] синуса, косинуса и квадратного корня...
просто задание дали человеку такое. это довольно частое явление, что студентам задают реализовывать функции/процедуры, которые есть в стандартных библиотеках.
Код:
function sin_(r:real):real;
begin
sin(r);
sin_:=r;
return r;
end;
begin
sin(r);
sin_:=r;
return r;
end;
зато потренировался с си на паскаль портировать)) и в ядре bsd покопался))
Вредно мешать Пасцаль с ЯваСкр... ик! %)