Perl - 72 bytes
$~=<>=~$"+$'*2;$_=1-$_*$`/$~--/$~*$`for($,,$;)x$';printf'%f
%f',$`*$,,$;
Or, counting command line options as 1 byte each, in 70 bytes:
#!perl -n
$-=/ /+$'*2;$_=1-$_*$`/$---/$-*$`for($,,$;)x$';printf'%f
%f',$`*$,,$;
Or, if you'll allow me Perl 5.8, in 63 bytes:
#!perl -p
$.+=$'<</ /;$_=1-$_*$`/$.--/$.*$`for($_=$#='%f
',$\)x$';$_*=$`
but why would you.
Edit: Compliance with the new rules. %f
rounds to 6 places by default, how convenient!
Algorithm
Examining the Taylor series for sin(x):
it can be seen that each term evenly divides every successive term. Because of this, it can be transformed rather effortlessly into a nested expression:
cos(x) transforms similarly, without the leading x, and denominator terms one smaller.
Additionally, this nested expression can be reformulated as a reverse recursive expression:
with s∞ = 0 and sin(x) = x·s1, which is ultimately what is used.
Ungolfed
<> =~ m/ /; # read one line from stdin, match a space
# prematch ($`) is now x, postmatch ($') is now n
($x, $n) = ($`, $'); # reassign, for clarity
$i = 2*$n + 1; # counting variable (denominators)
for (($s, $c)x$n) { # iterate over $s and $c, n times each
# compute the next term of the recursive expression
# note: inside this loop $_ is not the _value_
# of $s and $c alternately, it _is_ $s and $c
$_ = 1 - $_ * $x**2 / $i-- / $i;
}
# formated output
printf("%f\n%f", $x*$s, $c);
Sample Usage
$ echo 5 3 | perl sin-cos.pl
10.208333
14.541667
$ echo 8.555 13 | perl sin-cos.pl
0.765431
-0.641092
$ echo 9.26 10 | perl sin-cos.pl
-3.154677
-8.404354
$ echo 6.54 12 | perl sin-cos.pl
0.253986
0.967147
$ echo 5 1 | perl sin-cos.pl
5.000000
1.000000
$ echo 20 20 | perl sin-cos.pl
-5364.411846
-10898.499385
If you want to test this online, I recommend using compileonline.com. Copy-Paste the code into main.pl
, and the input into the STDIN
box, then Execute Script.