{{ message }}

Instantly share code, notes, and snippets.

# xtrp/sin_cos_functions.pl

Created Nov 26, 2020
Maclaurin/Taylor Series Calculation of Sin and Cos in Perl
 #!/usr/bin/perl use warnings; \$pi = 3.14159265358979323; # get the factorial of a number (x) # factorial(x) is the product of every number from 1 to N inclusive sub factorial { my (\$x) = @_; my \$n = 1; # n is the result # multiply n by every number from 1 to x inclusive my @nums_to_multiply = (1..\$x); for(@nums_to_multiply){ \$n *= \$_; } return \$n; } =begin get the result of the cos and sin formulas where the functions are sin(x radians) or cos(x radians), n is the start value (n = x for sin, n = 1 for cos), and i_start is the exponent and factorial base in the first term =cut sub computeSeries { \$ITERATIONS = 20; # iterations is twice the amount of terms to use my (\$x, \$n, \$i_start) = @_; my \$multiplier = 1; \$i = \$i_start; while(\$i < \$i_start + \$ITERATIONS) { \$multiplier *= -1; # alternates between addition and subtraction each term \$n += \$multiplier * ((\$x**\$i) / factorial(\$i)); # add or subtract ((x^i) / i!) from final result \$i += 2; # i increases by 2 each term } return \$n; } # get sin of x radians sub mySin { my (\$x) = @_; return computeSeries(\$x, \$x, 3); } # get cos of x radians sub myCos { my (\$x) = @_; return computeSeries(\$x, 1, 2); } # get sin of x degrees sub sinDeg { my (\$x) = @_; return mySin(\$x * \$pi / 180); } # get cos of x degrees sub cosDeg { my (\$x) = @_; return myCos(\$x * \$pi / 180); } # test the functions print(sin(\$pi / 6) . "\n"); # 0.5 print(sinDeg(45) . "\n"); # 0.7071 print(sinDeg(52) . "\n"); # 0.78801 print(cos(\$pi / 3) . "\n"); # 0.5 print(cosDeg(45) . "\n"); # 0.7071 print(cosDeg(52) . "\n"); # 0.615661

### shixilun commented Jan 4, 2021

 The implementation is correct but horribly inefficient.

### druud commented Jan 4, 2021 • edited

 To compare: ``````perl -Mstrict -MList::Util=reduce -wE' use constant PI => atan2(1,0) * 2; sub _c { my ( \$x, \$n, \$m )= @_; \$x+= 2*PI while \$x < 0; \$x-= 2*PI while 2*PI <= \$x; my \$x2= \$x * \$x; \$n//= \$x; my \$s= my \$d= 1; reduce { \$a + (\$s*= -1) * (\$n*= \$x2) / (\$d*= 2*\$b*(2*\$b+\$m) ) } \$n, 1..10; } sub LU_sin { _c shift, undef, 1 } sub LU_cos { _c shift, 1, -1 } for ( 2, 3, 4, 6 ) { my \$x= PI / \$_; say "sin(PI/\$_)=", LU_sin( \$x ); say "cos(PI/\$_)=", LU_cos( \$x ); } ' sin(PI/2)=1 cos(PI/2)=6.09227631828637e-17 sin(PI/3)=0.866025403784438 cos(PI/3)=0.5 sin(PI/4)=0.707106781186547 cos(PI/4)=0.707106781186547 sin(PI/6)=0.5 cos(PI/6)=0.866025403784439 ``````