I have been attempting to implement a function calculating values of the sine function. I know that there are several similar threads regarding this topic but my goal was to try to implement such function in my own way as an excercise. I suppose that the argument will be in range \$\left<-2\pi\, +2\pi\right>\$.
In the time being I have below given code in C++ language which seems to be working (I have compared the outputs of that code with the sine values calculated by the Excel).
#define PI 3.14
#define TABLE_SIZE 256
#define STEP_SIZE (2*PI/255)
double lut[TABLE_SIZE] = {
0.0000, 0.0245, 0.0490, 0.0735, 0.0980, 0.1223, 0.1467, 0.1709,
0.1950, 0.2190, 0.2429, 0.2666, 0.2901, 0.3135, 0.3367, 0.3597,
0.3825, 0.4050, 0.4274, 0.4494, 0.4712, 0.4927, 0.5139, 0.5348,
0.5553, 0.5756, 0.5954, 0.6150, 0.6341, 0.6529, 0.6713, 0.6893,
0.7068, 0.7240, 0.7407, 0.7569, 0.7727, 0.7881, 0.8029, 0.8173,
0.8312, 0.8446, 0.8575, 0.8698, 0.8817, 0.8930, 0.9037, 0.9140,
0.9237, 0.9328, 0.9413, 0.9493, 0.9568, 0.9636, 0.9699, 0.9756,
0.9806, 0.9852, 0.9891, 0.9924, 0.9951, 0.9972, 0.9988, 0.9997,
1.0000, 0.9997, 0.9988, 0.9974, 0.9953, 0.9926, 0.9893, 0.9854,
0.9810, 0.9759, 0.9703, 0.9640, 0.9572, 0.9498, 0.9419, 0.9333,
0.9243, 0.9146, 0.9044, 0.8937, 0.8824, 0.8706, 0.8583, 0.8454,
0.8321, 0.8182, 0.8039, 0.7890, 0.7737, 0.7580, 0.7417, 0.7251,
0.7080, 0.6904, 0.6725, 0.6541, 0.6354, 0.6162, 0.5967, 0.5769,
0.5566, 0.5361, 0.5152, 0.4941, 0.4726, 0.4508, 0.4288, 0.4065,
0.3840, 0.3612, 0.3382, 0.3150, 0.2917, 0.2681, 0.2444, 0.2205,
0.1966, 0.1724, 0.1482, 0.1239, 0.0996, 0.0751, 0.0506, 0.0261,
0.0016, -0.0229, -0.0475, -0.0719, -0.0964, -0.1208, -0.1451, -0.1693,
-0.1934, -0.2174, -0.2413, -0.2650, -0.2886, -0.3120, -0.3352, -0.3582,
-0.3810, -0.4036, -0.4259, -0.4480, -0.4698, -0.4913, -0.5125, -0.5334,
-0.5540, -0.5743, -0.5942, -0.6137, -0.6329, -0.6517, -0.6701, -0.6881,
-0.7057, -0.7229, -0.7396, -0.7559, -0.7717, -0.7871, -0.8020, -0.8164,
-0.8303, -0.8437, -0.8566, -0.8690, -0.8809, -0.8923, -0.9031, -0.9133,
-0.9230, -0.9322, -0.9408, -0.9488, -0.9563, -0.9632, -0.9695, -0.9752,
-0.9803, -0.9849, -0.9888, -0.9922, -0.9950, -0.9971, -0.9987, -0.9996,
-1.0000, -0.9998, -0.9989, -0.9975, -0.9954, -0.9928, -0.9895, -0.9857,
-0.9813, -0.9762, -0.9706, -0.9644, -0.9577, -0.9503, -0.9424, -0.9339,
-0.9249, -0.9153, -0.9051, -0.8944, -0.8832, -0.8714, -0.8591, -0.8463,
-0.8330, -0.8191, -0.8048, -0.7900, -0.7747, -0.7590, -0.7428, -0.7262,
-0.7091, -0.6916, -0.6736, -0.6553, -0.6366, -0.6175, -0.5980, -0.5782,
-0.5580, -0.5374, -0.5166, -0.4954, -0.4740, -0.4522, -0.4302, -0.4080,
-0.3854, -0.3627, -0.3397, -0.3166, -0.2932, -0.2696, -0.2459, -0.2221,
-0.1981, -0.1740, -0.1498, -0.1255, -0.1011, -0.0767, -0.0522, -0.0277
};
double sine(double x, double lut[TABLE_SIZE])
{
bool negateTableValue = false;
if (x < 0) {
// sin(-x) = -sin(x)
x = -x;
negateTableValue = true;
}
uint8_t index_01 = x/STEP_SIZE;
uint8_t index_02 = (index_01 + 1);
double aux = (lut[index_02] - lut[index_01])/STEP_SIZE*(x - index_01*STEP_SIZE) + lut[index_01];
if (negateTableValue) {
return -aux;
} else {
return aux;
}
}
The sine values calculation is based on the look-up table containing the pre-computed values of the sine function covering the whole period \$\left<0, 2\pi\right>\$ with 256 values. I have decided to use the linear interpolation method for improving the precision.
I have one doubt regarding the linear interpolation. Namely I have been using table with 256
entries but most of the solutions exploiting the linear interpolation use look-up table with one additional entry. I would say that it isn't necessary in my case because the index variables are uint8_t
type i.e. they can store values from range 0-255
. But I would like to know other ones opinion. Thank you in advance.