3 * fast mathematics routines.
7 * A Fast, Compact Approximation of the Exponential Function
9 * IDSIA, Lugano, Switzerland
10 * http://www.inf.ethz.ch/~schraudo/pubs/exp.pdf
12 * Base-2 exp, Laurent de Soras
13 * http://www.musicdsp.org/archive.php?classid=5#106
15 * Fast log() Function, by Laurent de Soras:
16 * http://www.flipcode.com/cgi-bin/msg.cgi?showThread=Tip-Fastlogfunction&forum=totd&id=-1
18 * Sin, Cos, Tan approximation
19 * http://www.musicdsp.org/showArchiveComment.php?ArchiveID=115
21 * fast floating point power computation:
22 * http://playstation2-linux.com/download/adam/power.c
31 #include "fastmath.hxx"
32 #define SGD_PI_2 1.57079632679489661923
35 * This function is on avarage 9 times faster than the system exp() function
36 * and has an error of about 1.5%
41 #if BYTE_ORDER == BIG_ENDIAN
49 double fast_exp(double val) {
50 const double a = 1048576/M_LN2;
51 const double b_c = 1072632447; /* 1072693248 - 60801 */
53 _eco.n.i = (int)(a*val + b_c);
59 * Linear approx. between 2 integer values of val. Uses 32-bit integers.
60 * Not very efficient but faster than exp()
62 double fast_exp2( const double val )
71 #if BYTE_ORDER == BIG_ENDIAN
72 ((*((int *) &ret)) &= ~(2047 << 20)) += (e + 1023) << 20;
74 ((*(1 + (int *) &ret)) &= ~(2047 << 20)) += (e + 1023) << 20;
78 ret = val - (e - 1024);
80 #if BYTE_ORDER == BIG_ENDIAN
81 ((*((int *) &ret)) &= ~(2047 << 20)) += e << 20;
83 ((*(1 + (int *) &ret)) &= ~(2047 << 20)) += e << 20;
94 float _fast_log2(const float val)
100 result *= 1.0/(1<<23);
101 result = result - 127;
103 tmp = result - floor(result);
104 tmp = (tmp - tmp*tmp) * mp;
108 float _fast_pow2(const float val)
113 float tmp = val - floor(val);
114 tmp = (tmp - tmp*tmp) * mp;
116 result = val + 127 - tmp;
118 *(int*)&result = (int)result;
125 * While we're on the subject, someone might have use for these as well?
126 * Float Shift Left and Float Shift Right. Do what you want with this.
128 void fast_BSL(float &x, register unsigned long shiftAmount) {
130 *(unsigned long*)&x+=shiftAmount<<23;
134 void fast_BSR(float &x, register unsigned long shiftAmount) {
136 *(unsigned long*)&x-=shiftAmount<<23;
142 * fastpow(f,n) gives a rather *rough* estimate of a float number f to the
143 * power of an integer number n (y=f^n). It is fast but result can be quite a
144 * bit off, since we directly mess with the floating point exponent.
146 * Use it only for getting rough estimates of the values and where precision
147 * is not that important.
149 float fast_pow(const float f, const int n)
153 l=*lp;l-=0x3F800000l;l<<=(n-1);l+=0x3F800000l;
158 float fast_root(const float f, const int n)
162 l=*lp;l-=0x3F800000l;l>>=(n-1);l+=0x3F800000l;
169 * Code for approximation of cos, sin, tan and inv sin, etc.
170 * Surprisingly accurate and very usable.
179 float fast_sin(const float val)
181 float fASqr = val*val;
182 float fResult = -2.39e-08f;
184 fResult += 2.7526e-06f;
186 fResult -= 1.98409e-04f;
188 fResult += 8.3333315e-03f;
190 fResult -= 1.666666664e-01f;
198 float fast_cos(const float val)
200 float fASqr = val*val;
201 float fResult = -2.605e-07f;
203 fResult += 2.47609e-05f;
205 fResult -= 1.3888397e-03f;
207 fResult += 4.16666418e-02f;
209 fResult -= 4.999999963e-01f;
216 float fast_tan(const float val)
218 float fASqr = val*val;
219 float fResult = 9.5168091e-03f;
221 fResult += 2.900525e-03f;
223 fResult += 2.45650893e-02f;
225 fResult += 5.33740603e-02f;
227 fResult += 1.333923995e-01f;
229 fResult += 3.333314036e-01f;
238 float fast_asin(float val)
240 float fRoot = sqrt(1.0f-val);
241 float fResult = -0.0187293f;
243 fResult += 0.0742610f;
245 fResult -= 0.2121144f;
247 fResult += 1.5707288f;
248 fResult = SGD_PI_2 - fRoot*fResult;
253 float fast_acos(float val)
255 float fRoot = sqrt(1.0f-val);
256 float fResult = -0.0187293f;
258 fResult += 0.0742610f;
260 fResult -= 0.2121144f;
262 fResult += 1.5707288f;
268 float fast_atan(float val)
270 float fVSqr = val*val;
271 float fResult = 0.0028662257f;
273 fResult -= 0.0161657367f;
275 fResult += 0.0429096138f;
277 fResult -= 0.0752896400f;
279 fResult += 0.1065626393f;
281 fResult -= 0.1420889944f;
283 fResult += 0.1999355085f;
285 fResult -= 0.3333314528f;