summaryrefslogtreecommitdiff
path: root/apps/fixedpoint.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/fixedpoint.c')
-rw-r--r--apps/fixedpoint.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/apps/fixedpoint.c b/apps/fixedpoint.c
index f9903f301f..fb89a8d30f 100644
--- a/apps/fixedpoint.c
+++ b/apps/fixedpoint.c
@@ -171,6 +171,35 @@ long fp_sqrt(long x, unsigned int fracbits)
171 171
172 return b; 172 return b;
173} 173}
174
175/* Accurate int sqrt with only elementary operations. (the above
176 * routine fails badly without enough iterations, more iterations
177 * than this requires -- [give that one a FIXME]).
178 * Snagged from:
179 * http://www.devmaster.net/articles/fixed-point-optimizations/ */
180unsigned long isqrt(unsigned long x)
181{
182 /* Adding CLZ could optimize this further */
183 unsigned long g = 0;
184 int bshift = 15;
185 unsigned long b = 1ul << bshift;
186
187 do
188 {
189 unsigned long temp = (g + g + b) << bshift;
190
191 if (x > temp)
192 {
193 g += b;
194 x -= temp;
195 }
196
197 b >>= 1;
198 }
199 while (bshift--);
200
201 return g;
202}
174#endif /* PLUGIN or CODEC */ 203#endif /* PLUGIN or CODEC */
175 204
176 205
@@ -256,6 +285,44 @@ long fp16_log(int x) {
256 y-=x>>15; 285 y-=x>>15;
257 return y; 286 return y;
258} 287}
288
289/**
290 * Fixed-point exponential
291 * taken from http://www.quinapalus.com/efunc.html
292 * "The code assumes integers are at least 32 bits long. The (non-negative)
293 * argument and the result of the function are both expressed as fixed-point
294 * values with 16 fractional bits. Notice that after 11 steps of the
295 * algorithm the constants involved become such that the code is simply
296 * doing a multiplication: this is explained in the note below.
297 * The extension to negative arguments is left as an exercise."
298 */
299long fp16_exp(int x)
300{
301 int t,y;
302
303 y=0x00010000;
304 t=x-0x58b91; if(t>=0) x=t,y<<=8;
305 t=x-0x2c5c8; if(t>=0) x=t,y<<=4;
306 t=x-0x162e4; if(t>=0) x=t,y<<=2;
307 t=x-0x0b172; if(t>=0) x=t,y<<=1;
308 t=x-0x067cd; if(t>=0) x=t,y+=y>>1;
309 t=x-0x03920; if(t>=0) x=t,y+=y>>2;
310 t=x-0x01e27; if(t>=0) x=t,y+=y>>3;
311 t=x-0x00f85; if(t>=0) x=t,y+=y>>4;
312 t=x-0x007e1; if(t>=0) x=t,y+=y>>5;
313 t=x-0x003f8; if(t>=0) x=t,y+=y>>6;
314 t=x-0x001fe; if(t>=0) x=t,y+=y>>7;
315 if(x&0x100) y+=y>>8;
316 if(x&0x080) y+=y>>9;
317 if(x&0x040) y+=y>>10;
318 if(x&0x020) y+=y>>11;
319 if(x&0x010) y+=y>>12;
320 if(x&0x008) y+=y>>13;
321 if(x&0x004) y+=y>>14;
322 if(x&0x002) y+=y>>15;
323 if(x&0x001) y+=y>>16;
324 return y;
325}
259#endif /* PLUGIN */ 326#endif /* PLUGIN */
260 327
261 328