# 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) = 1 / 0! - x^2 / 2! + x^4 / 4! - x^6 / 6! + ... + (-1)^k x^(2k) / (2k)! + ...


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?

### Your Task

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? – GamrCorps Apr 16 '17 at 18:24
• I'd say they technically isn't what pedant means, but that would be too meta. – PyRulez Apr 17 '17 at 2:05
• If your Boss wants you write a good or at least readable function, you're in the wrong place. – Roman Gräf Apr 17 '17 at 8:25
• A truly picky boss would want to calculate cosine using something a little more efficient (and accurate) than Taylor series... – PM 2Ring Apr 18 '17 at 11:49
• @PM2Ring That would not be picky, that would be being reasonable. Taylor series is really the crudest option. – user1997744 Apr 18 '17 at 15:51

# Pari/GP, 35 bytes

f(x,n)=sum(i=0,n-1,(-x^2)^i/(2*i)!)


Try it online!

## F#, 177 146 bytes

let rec f x=if x<2 then 1 else f(x-1)*x
let i n x=(pown -1.0 n)*(pown x (2*n))/float(f(2*n))
let t x k=seq{for j=0 to(k-1)do yield i j x}|>Seq.sum


Try it online!

Shaved off 31 bytes thanks to Emmanuel showing me operators in F# that I wasn't aware of. I had a look at Microsoft.FSharp.Core.Operators and found some useful stuff there. Thanks a million!

f is a recursive factorial function. i is one item in the series, and t is the actual Taylor Series itself - iterate through from 0 to k-1, evaluating i at each stage, and sum the results.

• You could try with the **exponential operator. – Emmanuel May 4 '18 at 15:46
• Ah, I wasn't aware that F# had an exponential operator! This is what I love about Code Golf - I'm inexperienced with F# so I didn't know about ** or any of the other goodies in Microsoft.FSharp.Core.Operators. Now I know about ** and pown and a load of other good things, and I can take 31 bytes off the solution. Thanks a lot, I really appreciate it! – Ciaran_McCarthy May 4 '18 at 22:03

# Java, 120 characters

package p;class C{double r;double c(double x,double c,long d,int i){return i>0?r+=c(x,-c/x/x,d/(4*i*i-2*i),--i)+c/d:r;}}


With comments and whitespaces:

## C.java

/*
* Class 'C' (for 'Cosine').
* Copyright (C) 2017 Gerold 'Geri' Broser (geribro@users.sourceforge.net)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package p;

/** Class 'C' (for Cosine).
*
* @author Gerold 'Geri' Broser
* @version 17.04.21
* @see https://codegolf.stackexchange.com/questions/116705/the-pedants-cosine
*/
class C {

/** The added up results of the polynomial's terms.
*/
double r;

/** This one-liner method 'c' (for calculate) returns the part (i=n-1) of a
*  cosine of a given angle 'x' that's calculated from the second term of a
*  Taylor series of n polynomial terms onwards (or backwards until the
*  second term [i=1], to be precise, see below).
*
*  It achieves this by doing the following:
*
* ● It doesn't calculate the first term since it is always 1 anyway.
*
* ● It uses recursion for calculating the terms of the polynomial.
*
* ● It calculates from the rightmost term back to the leftmost. Such avoiding
*   to keep the upper boundary stored till the end for the recursion's stop
*   condition.
*
* ● It is supplied with values for the counter and denominator of the
*   rightmost term at invocation. Such also the user can decide which
*   library to take for power and factorial.
*
* ● It calculates the counters and denominators for each term from scratch
*   at each recursion but uses the values calculated at the previous
*   recursion. Such the new values can be calculated by using trivial
*   parenthesis, division, multiplication, decrement and negation only.
*   This doesn't only save characters but probably is also faster than
*   power and factorial.
*   [It could be made be even faster for x=2^n, n ∈ N, because we can
*   use the unsigned right shift operator '>>>' instead of divisions then
*   (see method 'calculateForXisPowerOfTwo()' of class 'Cosine').]
*
* @param x angle (independent variable) in radians
* @param c counter of last term specified by index 'i' including proper sign
*          (see class 'CTest')
* @param d denominator of last term specified by index 'i' (see class 'CTest')
* @param i index of last term used in the calculation (=number of terms 'n'
*          minus 1; Σ's upper boundary)
*
* @see https://en.wikipedia.org/wiki/Taylor_series#Trigonometric_functions
*/

// Copy the following three lines to immediately after the function header for testing:
//  System.out.printf(
//          "c(): x:%4.1f  c:%24.17f  d:%,19d  i:%2d  t:%40.35f%n",
//          x, c, d, i, c / d);

// Position of 'i' is relevant here, since it is prefix-decremented inline!
double c( double x, double c, long d, int i ) {
return i > 0
? r += c(
x,
-c / x / x,
d / (4 * i * i - 2 * i),
--i )
+ c / d
: r;
} // c()
} // C


## CTest.java

/*
* Class 'CTest' (for 'Cosine Test').
* Copyright (C) 2017 Gerold 'Geri' Broser (geribro@users.sourceforge.net)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package p;

import org.apache.commons.math3.util.CombinatoricsUtils;

/** Test class for methods 'c' (for calculate) of class 'C' (for Cosine).
*
* @author Gerold 'Geri' Broser
* @version 17.04.21
* @see https://codegolf.stackexchange.com/questions/116705/the-pedants-cosine
*/
public class CTest {

/** The Unicode character 'ₛ' is the subscript character for 's'. It stands for the plural 's'
*  in the array's names. ('xs' wasn't matching my BMI. 'ns' looked like a system that we have
*  overcome since decades and like the German abbreviation for...I'm leaving that one out now.)
*
* @param args command line arguments
*/
public static void main( String[] args ) {

double[] xₛ = { .0, .5, .5, .5, .5, 2., 2. };
int[] nₛ = { 1, 1, 2, 4, 9, 2, 5 };

System.out.println(
"┌────┬─────┬───┬───────────────────────┐\n" +
"│ No │  x  │ n │        cos(x)         │\n" +
"├────┤─────┼───┼───────────────────────┤" );
for ( int i = 0; i < xₛ.length; i++ ) {

System.out.printf( "│ %d. │ %2.1f │ %d │ %,21.18f │%n",
i + 1,
xₛ[i], // x (angle)
nₛ[i]--, // n (number of terms of the polynomial, decreased for further processing as index)
1.0 + new C().c(
xₛ[i], // x (angle in radians)
Math.pow( -1, nₛ[i] ) // negate alternating starting with minus for the second term
* Math.pow( xₛ[i], 2 * nₛ[i] ), // counter for the rightmost term (c)
CombinatoricsUtils.factorial( 2 * nₛ[i] ), // denominator for the rightmost term (d)
nₛ[i] // index of last term of the polynomial
) );

} // for ( C test case )
System.out.println( "└────┴─────┴───┴───────────────────────┘" );
} // main()
} // CTest


## Output

┌────┬─────┬───┬───────────────────────┐
│ No │  x  │ n │        cos(x)         │
├────┤─────┼───┼───────────────────────┤
│ 1. │ 0,0 │ 1 │  1,000000000000000000 │
│ 2. │ 0,5 │ 1 │  1,000000000000000000 │
│ 3. │ 0,5 │ 2 │  0,875000000000000000 │
│ 4. │ 0,5 │ 4 │  0,877582465277777700 │
│ 5. │ 0,5 │ 9 │  0,877582561890372800 │
│ 6. │ 2,0 │ 2 │ -1,000000000000000000 │
│ 7. │ 2,0 │ 5 │ -0,415873015873015950 │
└────┴─────┴───┴───────────────────────┘