Programs to Compute Trig Functions in Python, JavaScript, & Perl (with Maclaurin Series)
Introduction
Have you ever wondered how your computer calculates certain mathematical functions, like division, or trigonometric functions like sine or cosine? Well, for some of these mathematical functions, there exist useful formulas to calculate very accurate results pretty easily. For sine and cosine, one commonly used formula looks like this:
And for cosine:
Note that the input of each function is in radians, not degrees.
The series used in both formulas is called a Maclaurin series (a type of Taylor series), and can be derived from the sine and cosine functions with a series expansion.
How the Programs Work
I've written programs to implement these two computations in three major scripting languages: Python, JavaScript, and Perl. These programs do not include any built-in trig functions or other utilities except the use of the in-built π constant in some cases. All code is CC0 licensed.
The approach I used creates a generalized function called computeSeries
which takes in x as the number to calculate the sine or cosine of, a starting number in the series (x for sine and 1 for cosine), and the exponent and factorial base in the first term of the series (3 for sine and 2 for cosine).
In calculating each series, I found that only about 10 terms in the series were needed to get a decently accurate result.
The programs additionally include utility functions for sine and cosine functions in degrees. The end of each program also includes a few tests of each function, which work as expected.
In Python
Feel free to view the below code as a GitHub Gist.
1from math import pi 2 3# round a number (x) to nearest 10 digits 4def rounded(x): 5 return round(x, 10) 6 7# get the factorial of a number (x) 8# factorial(x) is the product of every number from 1 to N inclusive 9def factorial(x): 10 n = 1; # n is the result 11 # multiply n by every number from 1 to x inclusive 12 for i in range(2, x + 1): 13 n *= i 14 return n 15 16""" get the result of the cos and sin formulas 17 where the functions are sin(x radians) or cos(x radians), 18 n is the start value (n = x for sin, n = 1 for cos), and 19 i_start is the exponent and factorial base in the first term """ 20def computeSeries(x, n, i_start): 21 iterations = 20 # iterations is twice the amount of terms to use 22 multiplier = 1 23 for i in range(i_start, i_start + iterations, 2): # i increases by 2 each term 24 multiplier *= -1 # alternates between addition and subtraction each term 25 next_term = (x**i) / factorial(i) # each term is (x^i) / i! 26 n += multiplier * next_term # add or subtract from final result 27 return n 28 29# get sin of x radians 30def sin(x): 31 return rounded(computeSeries(x, x, 3)) 32 33# get cos of x radians 34def cos(x): 35 return rounded(computeSeries(x, 1, 2)) 36 37# get sin of x degrees 38def sinDeg(x): 39 return sin(x * pi / 180) 40 41# get cos of x degrees 42def cosDeg(x): 43 return cos(x * pi / 180) 44 45# test the functions 46print(sin(pi / 6)); # 0.5 47print(sinDeg(45)); # 0.7071 48print(sinDeg(52)); # 0.78801 49 50print(cos(pi / 3)); # 0.5 51print(cosDeg(45)); # 0.7071 52print(cosDeg(52)); # 0.615661 53
In JavaScript
Feel free to view the below code as a GitHub Gist.
1// round a number (x) to nearest 10 digits 2const rounded = (x) => { 3 return parseFloat(x.toFixed(10)); 4} 5 6// get the factorial of a number (x) 7// factorial(x) is the product of every number from 1 to x inclusive 8const factorial = (x) => { 9 let n = 1; // n is the result 10 // multiply n by every number from 1 to x inclusive 11 for(let i = 2; i <= x; i++) { 12 n *= i; 13 } 14 return n; 15} 16 17/* get the result of the cos and sin formulas 18 where the functions are sin(x radians) or cos(x radians), 19 n is the start value (x for sin, 1 for cos), and i_start 20 is the exponent and factorial base in the first term */ 21const computeSeries = (x, n, i_start) => { 22 const iterations = 20; // iterations is twice the amount of terms to use 23 let multiplier = 1; 24 let i = i_start; 25 while(i < i_start + iterations) { 26 multiplier *= -1; // alternates between addition and subtraction each iteration 27 const next_term = (x**i) / factorial(i); // each term is (x^i) / i! 28 n += multiplier * next_term // add or subtract from final result 29 i += 2 // i increases by 2 each term 30 } 31 return n 32} 33 34// get sin of x radians 35const sin = (x) => { 36 return rounded(computeSeries(x, x, 3)); 37} 38// get cos of x radians 39const cos = (x) => { 40 return rounded(computeSeries(x, 1, 2)); 41} 42// get sin of x degrees 43const sinDeg = (x) => { 44 return sin(x * Math.PI / 180); 45} 46// get cos of x degrees 47const cosDeg = (x) => { 48 return cos(x * Math.PI / 180); 49} 50 51// test the functions 52console.log(sin(Math.PI / 6)); // 0.5 53console.log(sinDeg(45)); // 0.7071 54console.log(sinDeg(52)); // 0.78801 55 56console.log(cos(Math.PI / 3)); // 0.5 57console.log(cosDeg(45)); // 0.7071 58console.log(cosDeg(52)); // 0.615661 59
In Perl
Feel free to view the below code as a GitHub Gist.
1#!/usr/bin/perl 2use warnings; 3 4$pi = 3.14159265358979323; 5 6# get the factorial of a number (x) 7# factorial(x) is the product of every number from 1 to N inclusive 8sub factorial { 9 my ($x) = @_; 10 my $n = 1; # n is the result 11 # multiply n by every number from 1 to x inclusive 12 my @nums_to_multiply = (1..$x); 13 for(@nums_to_multiply){ 14 $n *= $_; 15 } 16 return $n; 17} 18 19=begin 20get the result of the cos and sin formulas 21where the functions are sin(x radians) or cos(x radians), 22n is the start value (n = x for sin, n = 1 for cos), and 23i_start is the exponent and factorial base in the first term 24=cut 25sub computeSeries { 26 $ITERATIONS = 20; # iterations is twice the amount of terms to use 27 my ($x, $n, $i_start) = @_; 28 my $multiplier = 1; 29 $i = $i_start; 30 while($i < $i_start + $ITERATIONS) { 31 $multiplier *= -1; # alternates between addition and subtraction each term 32 $n += $multiplier * (($x**$i) / factorial($i)); # add or subtract ((x^i) / i!) from final result 33 $i += 2; # i increases by 2 each term 34 } 35 return $n; 36} 37 38# get sin of x radians 39sub mySin { 40 my ($x) = @_; 41 return computeSeries($x, $x, 3); 42} 43# get cos of x radians 44sub myCos { 45 my ($x) = @_; 46 return computeSeries($x, 1, 2); 47} 48# get sin of x degrees 49sub sinDeg { 50 my ($x) = @_; 51 return mySin($x * $pi / 180); 52} 53# get cos of x degrees 54sub cosDeg { 55 my ($x) = @_; 56 return myCos($x * $pi / 180); 57} 58 59# test the functions 60print(sin($pi / 6) . "\n"); # 0.5 61print(sinDeg(45) . "\n"); # 0.7071 62print(sinDeg(52) . "\n"); # 0.78801 63 64print(cos($pi / 3) . "\n"); # 0.5 65print(cosDeg(45) . "\n"); # 0.7071 66print(cosDeg(52) . "\n"); # 0.615661 67
Conclusion
I hope this helps in understanding how computers and languages would go about calculating trigonometric functions like sine and cosine. If you'd like to read more about how exactly mathematical formulas used to calculate the trig functions are derived, I would recommend taking a look at the videos on Taylor and Maclaurin series by Khan Academy.
These programs are all licensed under CC0, so feel free to use any of the code as you wish, without attribution.
Thanks for scrolling.
— Gabriel Romualdo, December 31, 2020