# How to calculate Sin function quicker and more precisely?

I want to calculate `y(n)=32677Sin(45/1024•n)`, where `y` is an integer and `n` ranges from 0 to 2048. How can I make this process quicker and more precisely? Now I want to show you a reference answer: Since `Sin(a+b)=Sin(a)Cos(b)+Cos(a)Sin(b)` And `Cos(a+b)=Cos(a)Cos(b)-Sin(a)Cos(b)`. So I can store `Sin(45/1024•1)` and `Cos(45/1024•1)` only.Then use this formula:

`Sin(45/1024•2)=Sin(45/1024•1+45/1024•1)`, `Cos(45/1024•2)=Cos(45/1024•1+45/1024•1)`, `Sin(45/1024•n)=Sin(45/1024•(n-1)+45/1024•1)`, `Cos(45/1024•n)=Cos(45/1024•(n-1)+45/1024•1)` , This way maybe quicker without storing large array.

• This question is appropriate for Programmers, assuming the intention is to learn about the appropriate algorithms and/or data structures from the perspective of software engineering concerns. Oct 8 '12 at 13:19
• That 45 is a bit suspect; it makes me think you want `sin(x)` where `x` is in degrees. If that's the case, you need to be aware that the argument to the trig functions is typically in radians. The argument is in radians in C++, which is how this question is tagged. Oct 8 '12 at 14:19
• Why do you need this question answered? What's the application? Oct 9 '12 at 0:00
• How accurate do you need the result to be? Oct 9 '12 at 2:06
• @dan04 Since y is an integer, I need it accurate as an integer . Oct 9 '12 at 4:03

If `n` ranges from 0 to 2048, you can pre-calculate the values, store then in an array. `y(n)` would become `values[n]`.

• +1 and you can interpolate for any values in between (if that's a possibility). Oct 8 '12 at 13:19
• That's a viable option, though I'd still profile it to make sure it is more efficient than calculating it (e.g. the FPU's `fsin` might be used and be more cache-friendly than some array). Oct 8 '12 at 13:20
• How about not storing value[n]? Oct 8 '12 at 13:24
• Trigonometric functions are very slow to compute on the fly. I'm pretty sure every fast implementation uses pre-computed values. Since sin() and cos() are periodic, you only need to store the first 90 degrees. You can return -sin(), or sin(90 - the angle), or -sin(90 - the angle) depending on the quadrant. You can also define cos() in terms of sin(). If you know the possible range of input values, you can pre-compute and only store the values you need for your program. If not, interpolation between a limited number of values may be your fastest option. Oct 8 '12 at 13:39
• @Glen: Sin values are between -1 and 1, so it will actually fit in 16-bit unsigned. Oct 9 '12 at 9:20

Compute the table at compile time instead of run time.

You're doing a 2048-element table of 16-bit scaled integer values.

Write a cheap Matlab script, with a print that gives a data line suitable for your final programming language. Cut-and-paste the result into your source code, as a constant data table, and do a table lookup at run time. This pushes the initial computation time off into the build cycle, instead of the program startup time.

• How much runtime does this save compared to the extra programmer cost? Oct 8 '12 at 21:37
• Quick and dirty. Nice. Aug 20 '14 at 2:21

Given the form of the function, the natural answer is the CORDIC algorithm. It's a much cleaner approach than the breakdown in the question. On the other hand, the table it needs is far, far smaller than the table others have suggested.