The Pedant's Cosine

My boss just told me to write a cosine function. Being a good math geek, my mind immediately conjured the appropriate Taylor Series.

$$\cos(x) = \frac 1 {0!} - \frac {x^2} {2!} + \frac {x^4} {4!} - \frac {x^6} {6!} + \cdots + \frac{(-1)^k \times x^{2k}} {(2k)!} + \cdots$$

However, my boss is very picky. He would like to be able to specify exactly how many terms of the Taylor Series to compute. Can you help me write this function?

Given a floating point value $$\x\$$ from $$\0\$$ to $$\2\pi\$$ and a positive integer $$\n\$$ less than $$\100\$$, compute the sum of the first $$\n\$$ terms of the Taylor series given above for $$\\cos(x)\$$.

This is , so shortest code wins. Input and output can be taken in any of the standard ways. Standard loopholes are forbidden.

Notes

• Input can be taken in any reasonable form, as long as there is a clear separation between $$\x\$$ and $$\n\$$.
• Input and output should be floating-point values, at least as accurate as calculating the formula using single-precision IEEE floating point numbers with some standard rounding rule.
• If it makes sense for the language being used, computations may be done using exact rational quantities, but the input and output shall still be in decimal form.

Examples

 x  |  n | Output
----+----+--------------
0.0 |  1 | 1.0
0.5 |  1 | 1.0
0.5 |  2 | 0.875
0.5 |  4 | 0.87758246...
0.5 |  9 | 0.87758256...
2.0 |  2 | -1.0
2.0 |  5 | -0.4158730...

• I'm assuming that n is also greater than 0? Commented Apr 16, 2017 at 18:24
• I'd say they technically isn't what pedant means, but that would be too meta. Commented Apr 17, 2017 at 2:05
• If your Boss wants you write a good or at least readable function, you're in the wrong place. Commented Apr 17, 2017 at 8:25
• A truly picky boss would want to calculate cosine using something a little more efficient (and accurate) than Taylor series... Commented Apr 18, 2017 at 11:49
• @PM2Ring That would not be picky, that would be being reasonable. Taylor series is really the crudest option. Commented Apr 18, 2017 at 15:51

Operation Flashpoint scripting language, 165 157 bytes

F={x=_this select 0;n=_this select 1;i=0;r=0;while{i<n*2}do{r=r+x^i/(i call{c=_this;j=c-1;while{j>0}do{c=c*j;j=j-1};if(c<1)then{c=1};c})*(-1)^(i/2);i=i+2};r}


Call with:

hint format["%1\n%2\n%3\n%4\n%5\n%6\n%7",
[0.0, 1] call f,
[0.5, 1] call f,
[0.5, 2] call f,
[0.5, 4] call f,
[0.5, 9] call f,
[2.0, 2] call f,
[2.0, 5] call f]


Output:

Input and output should be floating-point values, at least as accurate as calculating the formula using single-precision IEEE floating point numbers with some standard rounding rule.

I'm fairly sure that the numbers are single-precision IEEE floating point numbers, even though in the printed output the longer decimals are not that precise. It is the printing that rounds the numbers like that, actually the numbers are more precise.

For instance, a=1.00001;b=1.000011;hint format["%1\n%2\n%3", a, b, a==b] will output this:

1.00001
1.00001
false


So clearly the actual precision of the numbers is greater than the printed precision.

• But why?
– orlp
Commented Apr 16, 2017 at 23:31
• @orlp Why not ? Commented Apr 16, 2017 at 23:33
• @orlp I think the more appropriate question to ask is: why isn't the Operation Flashpoint scripting language a variant of ArnoldC? Commented Apr 17, 2017 at 16:40
• Hmmm… do you enter the input by shooting a given number of rounds [n] to the given compass direction [x]? 😍 Operation Flashpoint! Commented Apr 18, 2017 at 8:35
• @Mormegil Well, generally no, but that can be done with this piece of code: dir=-1;num=1;player addEventHandler ["fired", {_dir=getdir (nearestObject [_this select 0, _this select 4]);if (dir < 0) then {dir = _dir} else {if (abs(dir - _dir) < 5) then {num = num + 1} else {hint format["%1", [dir*(pi/180), num] call F];dir=-1;num=1}}}] - Shooting to some direction increments the counter, and then shooting to another direction calls the cosine function with the earlier direction and the number of shots in that direction. Commented Apr 18, 2017 at 10:10

05AB1E, 14 11 bytes

FIn(NmN·!/O


Try it online!

Explanation

F                # for N in [0 ... n] do
In              # push (x^2)
(             # negate
Nm           # raise to the Nth power
N·!        # push (2*N)!
/       # divide
O      # sum

• @JamesHolderness: Yes, the language has gone through a pretty major overhaul since then. A weird bug seem to have afflicted ², but it can instead be replaced by I. Commented Jan 3, 2018 at 19:08

MATL, 14 bytes

U_iqE:2ep/YpsQ


Explanation with example

All numbers have double precision (this is the default).

Consider inputs x = 2.0, n = 5.

U_     % Implicitly input x. Square and negate
% STACK: -4
iqE    % Input n. Subtract 1, multiply by 2
% STACK: -4, 8
:      % Range
% STACK: -4, [1 2 3 4 5 6 7 8]
2e     % Reshape into a 2-row matrix
% STACK: -4, [1 3 5 7;
%             2 4 6 8]
p      % Product of each column
% STACK: -4, [2 12 30 56]
/      % Divide, element-wise
% STACK: [-2 -0.333333333333333 -0.133333333333333 -0.0714285714285714]
Yp     % Cumulative product of array
% STACK: [-2 0.666666666666667 -0.0888888888888889 0.00634920634920635]
s      % Sum of array
% STACK: -1.41587301587302
Q      % Add 1. Implicitly display
% STACK: -0.41587301587302


Mathematica, 494139 31 bytes

Sum[(-#^2)^k/(2k)!,{k,0,#2-1}]&


Old, more "fun" version: (39 bytes)

Normal@Series[Cos@k,{k,0,2#2-2}]/.k->#&


Saved 10 bytes thanks to @Pavel and 8 thanks to @Greg Martin!

• While Mathematica's Series capability is indeed awesome and fun, it turns out the by-hand implementation Sum[(-#^2)^k/(2k)!,{k,0,#2-1}]& is shorter here. Commented Apr 16, 2017 at 19:05

Jelly, 12 11 bytes

ḶḤµ⁹*÷!_2/S


Try it online!

How?

ḶḤµ⁹*÷!_2/S - Main link: n, x           e.g. 5, 2.0
Ḷ           - lowered range(n)              [0,1,2,3,4]
Ḥ          - double (vectorises)           [0,2,4,6,8]
µ         - monadic chain separation (call that i)
⁹        - link's right argument         2.0
*       - exponentiate(i) (vectorises)  [1.0,4.0,16.0,64.0,256.0]
!     - factorial(i) (vectorises)     [1,  2,  24,  720, 40320]
÷      - divide (vectorises)           [1.0,2.0,0.6666666666666666,0.08888888888888889,0.006349206349206349]
2/  - pairwise reduce by:
_    -     subtraction               [-1.0,0.5777777777777777,0.006349206349206349]
S  - sum                           -0.41587301587301617


Jelly, 22 bytes

-*ð×ø⁹*⁸²ð÷ø⁸Ḥ!
⁸R’Ç€S


This is a full program which takes n as the first argument and x as the second.

Explanation:

              Creates a function to compute each term in the series.
Its argument we will call k, eg k=3 computes 3rd term. Take x=2 for example.
-*           Computes (-1)^k. Eg -1
ð×ø        Multiplies by the quantity of
⁹             x.
*             to the power of
⁸             k
²             ...squared. Eg -1 × (2³)²
ð÷ø        divides by the quantity of
⁸              k
Ḥ             doubled
!               ...factorial. Eg -1 × (2³)²/(6!).

Main link, first argument n and second argument n. Eg n=4, x=2.
⁸R            Creates range(n). Eg [1,2,3,4]
’                Decrements each element. Eg [0,1,2,3]
Ç€            Maps the above function over each element. Eg [1,-2,0.666,-0.0889]
S               Sum all all of the elements.  Eg -0.422.

• Welcome to PPCG! Commented Apr 16, 2017 at 22:16

Python, 54 bytes

f=lambda x,n,t=1,p=1:n and t+f(x,n-1,-t*x*x/p/-~p,p+2)


If using Python 2, be sure to pass x as a float, not an integer, but I my understanding is that it doesn't matter if you're using Python 3.

• 4 years late, but 46 bytes
– ovs
Commented Aug 11, 2021 at 8:16

C, 71 bytes

using Horner scheme

float f(n,x)float x;{float y;for(n+=n;n;)y=1-(y*x*x/n--)/n--;return y;}


Ungolfed version:

float f(n,x) float x;
{
float y = 0.0;
for(n = 2*n; n>0; n -= 2)
{
y = 1-y*x*x/n/(n-1);
}
return y;
}

• On which platform does this work? Commented Apr 18, 2017 at 9:52

TI-Basic, 41 40 bytes

Prompt X,N
sum(seq((-(X+1E-49)2)^Q/((2Q)!),Q,0,N-1

1E-49 is added to the angle because TI-Basic throws an error for 0^0, it's just large enough to not cause the error, and it is not large enough to change the answer.

• -3 bytes I suppose: X+1e-49 => X+e-49 and .../((2Q)!) => .../(2Q)! Commented Apr 20, 2021 at 15:11
• or even better (-(X+1e-49)²)^Q => (e-99-X²)^Q Commented Apr 20, 2021 at 21:16

R, 7064 47 bytes

function(x,n,m=1:n-1)sum((-x^2)^m/gamma(2*m+1))


Try it online!

• uses gamma(n+1) instead of factorial(n)
• 1:n-1 is equivalent to 0:(n-1)

Thanks to Dominic van Essen for golfing 17 bytes off by using a basic R feature: vectorization!

• Is there a reason that you didn't use vectorization...? Commented Apr 20, 2021 at 15:15
• @DominicvanEssen probably because I was a young R golfer, so excited to use sapply that I completely overlooked vectorization! Commented Apr 20, 2021 at 16:18

C, 96 bytes

Recursive Live

f(n){return n?n*f(n-1):1;}float c(n,x)float x;{return n?c(n-1,x)+pow(-1,n)*pow(x,2*n)/f(2*n):1;}


Detailed

f(n) // factorial(n)
{
return n ?   // n != 0 ?
n*f(n-1) // n! = n * (n-1)!
: 1;         // 0! = 1
}

float c(n,x)float x; // cos(x) with n+1 terms
{
return n ?        // n != 0 ?
c(n-1, x)     // cos(x) (n-1)th term
+ pow(-1, n)  // + (-1)^n
* pow(x, 2*n) // * x^(2n)
/ f(2 * n)    // / (2n)!
: 1;              // cos(x) at n=0
}


Progressive Recursive, 133 bytes Live

#define F float
#define c(x,n) 1+g(1,n,x,1,1,1)
F g(F i,F n,F x,F s,F p,F f){s=-s;p*=x*x;f*=i;return i<n?g(i+1,n,x,s,p,f)+s/2*p/f:0;}


Detailed

#define F float // shorthand float

#define c(x,n) 1+g(1,n,x,1,1,1) // macro function

F g(F i,F n,F x,F s,F p,F f)
{
s = -s;   // (-1)^n = (-1) * (-1)^(n-1)
p *= x*x; // x^(2n) =  x^2 * x^(2(n-1))
f *= i;   //    2n! =    2 * (1*2*..*n)

return i < n ?       // i = 0 .. n-1
g(i+1,n,x,s,p,f) // next term
+ s / 2 * p / f  // s*p/2f = s/2*p/f
: 0;             // don't compute nth term
}

• 96b version c(0.5, 80) => NaN, for overflow f(80)=0
– l4m2
Commented Jan 3, 2018 at 6:33
• @l4m2 recursive functions are here for the purpose of golfing, but they're impractical as they can easily overflow as the number of calls exceed the call-stack limit, & even with higher limits it's a waste of resource, for the solution above try smaller numbers. Commented Jan 3, 2018 at 12:58
• Problem directly say n<100 so you at least don't go that far in the range. Not stack overflow
– l4m2
Commented Jan 3, 2018 at 13:25
• If problem say n<100 and you use O(2^n) solution I guess it's okay, as long as it eventually retuan the result
– l4m2
Commented Jan 3, 2018 at 13:26
• FYI, the NaN result has got nothing to do with recursion - it's an overflow of the factorial calculation which is using integers when it should be using floats (198! is never going to fit in an int). Commented Jan 3, 2018 at 19:11

JavaScript (ES6), 46 bytes

f=
x=>g=(n,t=1,p=0)=>n&&t+g(--n,-t*x*x/++p/++p,p)
<div oninput=o.textContent=f(x.value)(n.value)><input id=x><input type=number min=1 value=1 id=n><pre id=o>1

Takes curried inputs (x)(n).

• Why not make it a snippet? Commented Apr 17, 2017 at 4:27

oK, 38 bytes

This also works in k, but takes 39 bytes because one ' has to be written as /: instead (at least, in kmac 2016.06.28 it does).

{+/(y#1 -1)*{(*/y#x)%*/1+!y}.'x,'2*!y}


Explanation:

Let's start with the middle bit. (*/y#x) is exponentiation, it is equivalent to x^y. */1+!y would be y!, or y factorial. % is division. Therefore the function in the middle is middle(x,y) = (x^y)/(y!).

Now the bit on the right, to which the function above gets applied. 2*!y is {0, 2, 4, ..., 2*(y-1)}. x,' prepends x to every item in that list, turning it into {(x, 0), (x, 2), (x, 4), ..., (x, 2*(y-1))}. The .' then applies middle to every pair of numbers (map, essentially).

Finally, (y#1 -1)* multiplies the result by 1 or -1 (alternating), and +/ takes the sum.

f x n=sum$map(\i->(-1)^i*x^(2*i)/fromIntegral(product[1..2*i]))[0..n-1]  This is a pretty boring answer that's not too hard to decipher. The fromIntegral really bites, though. (The / operator requires operands of the same numeric type in Haskell, and coercing between numeric types is not allowed without a wordy function.) • A list comprehension can save you a few bites: f x n=sum[(-1)^i*x^(2*i)/fromIntegral(product[1..2*i])|i<-[0..n-1]] Commented Apr 17, 2017 at 0:08 • Welcome to PPCG and Haskell golfing in particular! Commented Apr 17, 2017 at 7:19 Jelly, 12 bytes ²N*Ḷ}©÷®Ḥ!¤S  Try it online! How it works ²N*Ḷ}©÷®Ḥ!¤S Main link. Left argument: x. Right argument: n ² Square; yield x². N Negate; yield -x². © Call the link to the left and copy the result to the register. Ḷ} Call unlength on the right argument, yielding [0, 1, ..., n-1]. * Yield [1, -x², ..., (-x²)**(n-1)]. ¤ Combine the three links to the left into a niladic chain. ® Yield the value in the register, [0, 1, ..., n-1]. Ḥ Unhalve; yield [0, 2, ..., 2n-2]. ! Factorial; yield [0!, 2!, ..., (2n-2)!]. ÷ Division; yield [1/0!, -x²/2!, ..., (-x²)**(n-1)/(2n-2)!]. S Take the sum.  Pyth, 16 bytes sm_Fc^vzyd.!yddU  Accepts n first, then x. Example run. Haskell, 61 bytes x#n=sum[(-1*x^2)^i/fromIntegral(product[1..2*i])|i<-[0..n-1]]  This seemed different enough from the other Haskell solution to warrant a separate answer. Implementation should be pretty self-explanatory—call with x#n where x is the number the cosine of which is to be computed and n is the order of the partial sum to be taken. • You can save quite a few bytes by removing the fromIntegral and using ** in place of ^, such as this Commented May 4, 2018 at 4:33 • x#n=sum[(-x*x)**i/product[1..2*i]|i<-[0..n-1]] saves 3 more bytes. – lynn Commented May 4, 2018 at 12:14 Pyt, 3734 33 bytes ←←ĐĐ↔3Ș1~⇹ř⁻^04Ș⇹ř⁻^²*0↔ř⁻2*!+/+Ʃ  J, 26 24 Bytes +/@:(!@]%~^*_1^2%~])2*i.  -2 bytes thanks to @cole I originally planned to use a cyclic gerund to alternate between adding and subtracting, but couldn't get it to work. Explanation:  2*i. | Integers from 0 to 2(n-1) ( ) | Dyadic train: _1^-:@] | -1 to the power of the left argument ^* | Times left arg to the power of right arg !@]%~ | Divided by the factorial of the right arg +/@: | Sum  • 24 bytes: +/@:(!@]%~^*_1^2%~])2*i. Gonna investigate a cyclic gerund: it probably failed since J evaluates / right-to-left so you need to use |. (or maybe you accounted for this and still had difficulty). – cole Commented Jan 3, 2018 at 8:30 Perl 6, 53 bytes {(sum (1,*i*$^x...*)[^2*$^n] »/»(1,|[\*] 1..*)).re}  Try it online! This actually computes the complex exponential e for twice the number of requested terms and then takes the real part. Julia, 37 bytes x$n=1>(n-=1)||x$n+(-x^2)^n/prod(1:2n)  Try it online! MATLAB with Symbolic Math Toolbox, 57 bytes @(x,n)eval(subs(taylor(sym('cos(x)'),'Order',2*n),'x',x))  This defines an anonymous function with that takes double inputs x,n and outputs the result as a double. Example (tested on R2015b): >> @(x,n)eval(subs(taylor(sym('cos(x)'),'Order',2*n),'x',x)) ans = @(x,n)eval(subs(taylor(sym('cos(x)'),'Order',2*n),'x',x)) >> f = ans; format long; f(0,1), f(0.5,1), f(0.5,2), f(0.5,4), f(0.5,9), f(2,2), f(2,5) ans = 1 ans = 1 ans = 0.875000000000000 ans = 0.877582465277778 ans = 0.877582561890373 ans = -1 ans = -0.415873015873016  JavaScript ES7 60 bytes x=>a=n=>--n?(-1)**n*x**(2*n)/(f=m=>m?m*f(m-1):1)(2*n)+a(n):1 x=>a=n=> // Curry-d function, it basically returns another function --n? :1 // subtract one from n. If n - 1 is 0, return 1 (-1)**n* // This generates the sign of the number x**(2*n)/ // This creates the part before the division, basicaly x^2n (f=m=>m?m*f(m-1):1)(2*n) // This creates a recursive factorial function and calls it with 2n +a(n) // Recursively call the function. This adds the elements of the taylor series together  To use it: Press F12, type in the function and then do c(x)(n)  C 144 130 bytes F(m){int u=1;while(m)u*=m--;return u;}float f(float x,n){float s;for(int i=1;i<n;i++)s+=pow(-1,i)*pow(x,2*i)/(F(2*i));return 1+s;}  Ungolfed Version: //Function to calculate factorial int F(int m) { int u=1; while(m>1) u*=m--; return u; } //actual function called in main function float f(float x, int n) { float s=0.0; for(int i=1;i<=n-1;i++) s+=pow(-1,i)*pow(x,2*i)/(F(2*i)); return 1+s; }  Thanks Kevin for saving some bytes! • You can save a few bytes by massaging the function definitions: F(m){...}f(x,n)float x;{...} Commented Apr 19, 2017 at 3:03 • Since u * 1 == u, you can make the loop in the first function either while(m)u*=m-- or u=m;while(--m)u*=m (same length) Commented Apr 19, 2017 at 3:12 • i<=n-1 is the same as i<n Commented Apr 19, 2017 at 3:17 • @Kevin Thanks, you're absolutely right, have not golfed in a while now. :) Commented Apr 20, 2017 at 16:20 • 101 bytes Commented Nov 27, 2018 at 0:59 Tcl, 126 bytes proc c {x n k\ 0 r\ 0} {proc F n {expr$n?($n)*\[F$n-1]:1}
time {set r [expr $r+-1**$k*$x**(2*$k)/[F 2*$k]] incr k}$n
set r}


Try it online!

Stax, 12 bytes

ü┘·.ⁿYeò≥Vîû


Run and debug it

Unpacked, ungolfed, and commented, it looks like this.

            Input is x n
Z           Push a zero underneath the top.  The stack is now x 0 n
D           Run the rest of the program n times.
xJNi|*    (-x*x)^i where i is the iteration index
iH|F/     divide that by factorial(2i)
+         add to the running total so far
final result is implicitly printed


Run this one

Desmos, 36 bytes

\sum_{k=0}^{n-1}{(-1)^kv^{2k}/(2k)!}


View it on Desmos

Unfortunately, not a ton to golf here.

• \sum_{k=0}^{n-1}{(-v^2)^k/(2k)!} for 32 bytes
– att
Commented Apr 20, 2021 at 16:58

Wolfram Language (Mathematica), 30 bytes

Normal[Cos@x+O@x^(2#2)]/.x->#&


Try it online!

Mathematica has a more (byte-)efficient way to generate SeriesData objects than Series. O[x]^p truncates the power series of the function at the pth power.

Husk, 20 bytes

⌊*!9İ⁰ṁ§/ȯΠḣD^o_□⁰ŀ


Try it online!

Outputs sign + 9 decimal places; the initial decimal point is implicit.

14 bytes (ṁ§/ȯΠḣD^o_□⁰ŀ) to calculate the cosine, plus 6 bytes (⌊*!9İ⁰) to extract the decimal representation from the a rational number...

MMIX, 60 bytes (15 instrs)

cos SETH $5,#3FF0 // E0053FF0: one = 1.0 SETL$2,0           // E3020000: twon = 0
SET  $3,$5          // C1030500: term = one
FMUL $4,$0,$0 // 10040000: numer = x *. x SETL$0,0           // E3000000: accum = 0
INCH $4,#8000 // E4048000: numer = -.numer 0H FADD$0,$0,$3       // 04000003: loop: accum +.= term
FADD $255,$2,$5 // 04FF0205: temp = twon +. 1 FADD$2,$255,$5     // 0402FF05: twon = temp +. 1
FMUL $255,$255,$2 // 10FFFF02: temp *.= twon FDIV$255,$4,$255   // 14FF04FF: temp = numer /. temp
FMUL $3,$3,$255 // 100303FF: term *.= temp SUBU$1,$1,1 // 27010101: count-- PBZ$1,0B          // 5301FFF9: likelyif(!count) goto loop
POP  1,0            // F8010000: return(accum)


This is a really simpleminded algorithm. I managed to avoid using more than three stack temporaries ($255 is global and free for temporary use, any register numbered less than 32 is guaranteed on-stack). A few clever tricks and misc notes: SET$X,$Y is a short version of OR$X,\$Y,0;
it's nice that 1.0 fits entirely in the top quarter of a float, otherwise we would have had to use another instruction to set it;
PBZ is a predicted branch (faster if taken) if the register operand is 0;
the 0H is a local label that the 0B refers back to; and POP a,b means return a local variables and skip b instructions after the function call.