I am working on generation 3d perlin noise. The C# Math library seems like overkill for what I need since most of its functions use double percision. I use Math.Sin() in several places to generate the noise. Does anyone know of a faster sine function?
3 Answers
You can use a parabola to aproximate the value of the sine function. This has the advantage of having the roots at exactly -pi/2 and pi/2 which is usually not the case with other fast approximations based on the TaylorSeries or MaclaurinSeries.
public float Sin(float x) { const float B = 4 / PI; const float C = -4 / (PI*PI); return -(B * x + C * x * ((x < 0) ? -x : x)); } Here is a comparison to the actual sine function:

- 3\$\begingroup\$ This is indeed a great solution. Here is an excellent article from devmaster.net which describes why this works and gives some implementation details: devmaster.net/forums/showthread.php?t=5784 \$\endgroup\$reverbb– reverbb2010-10-23 20:25:30 +00:00Commented Oct 23, 2010 at 20:25
- \$\begingroup\$ I don't know about C#, but the abs() function in most C environments will likely be faster than a branch (the ?: operator), when optimized. \$\endgroup\$user744– user7442010-10-23 20:50:35 +00:00Commented Oct 23, 2010 at 20:50
- 3\$\begingroup\$ I removed the Math.Abs() call because I assumed that this code might run on the Xbox 360 or Windows Phone 7. The JIT compiler on Xbox 360 does not inline anything. A call to Math.Abs() is actually more expensive. \$\endgroup\$zfedoran– zfedoran2010-10-23 21:09:39 +00:00Commented Oct 23, 2010 at 21:09
- \$\begingroup\$ @reverbb Link is 404. Here is a cached copy. \$\endgroup\$Daniel– Daniel2015-01-13 00:36:09 +00:00Commented Jan 13, 2015 at 0:36
- 1\$\begingroup\$ @zfedoran Why do you negate the return value? It appears to be a negative sine wave. \$\endgroup\$Daniel– Daniel2015-01-13 01:36:07 +00:00Commented Jan 13, 2015 at 1:36
What is the range of input values to your sin() function? For what you're using it for, it sounds like they might be limited, which means you could pre-compute the values. For instance, if you're rounding up the input values to the nearest degree, then you only have 360 possible values - just pre-compute them and store in a table.
If you need slightly more values, say to one decimal place, you could interpolate from the table - I'm not familiar with perlin noise, but the word "noise" seems to indicate it doesn't require high accuracy. :) (You could also just make a larger table, 3600 entries isn't much space).
- 3\$\begingroup\$ If speed is your number-one concern, and you do not mind sacrificing a bit of accuracy, this is the best answer. \$\endgroup\$AttackingHobo– AttackingHobo2010-10-24 21:07:57 +00:00Commented Oct 24, 2010 at 21:07
- 2\$\begingroup\$ I don't know about "best" - As shown in another answer, you can get another very good approximation in five ops + abs (the speed of which depends on your arch / compiler, but is often branchless). If the lookup table is not in cache, it's going to be much slower. \$\endgroup\$user744– user7442010-10-26 12:31:24 +00:00Commented Oct 26, 2010 at 12:31
You might want to read this too, it's got fast sine and cosine approximations
- 1\$\begingroup\$ This link is 404. But you can find a backup here: web.archive.org/web/20110925033606/http://lab.polygonal.de/2007/… \$\endgroup\$eisberg– eisberg2013-06-26 12:21:23 +00:00Commented Jun 26, 2013 at 12:21