diff options
Diffstat (limited to 'apps/fixedpoint.c')
-rw-r--r-- | apps/fixedpoint.c | 67 |
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/ */ | ||
180 | unsigned 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 | */ | ||
299 | long 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 | ||