diff options
Diffstat (limited to 'apps/plugins/lib/fixedpoint.c')
-rw-r--r-- | apps/plugins/lib/fixedpoint.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/apps/plugins/lib/fixedpoint.c b/apps/plugins/lib/fixedpoint.c index cf69d9c31b..88c2f6ea54 100644 --- a/apps/plugins/lib/fixedpoint.c +++ b/apps/plugins/lib/fixedpoint.c | |||
@@ -202,3 +202,33 @@ long cos_int(int val) | |||
202 | } | 202 | } |
203 | return 0; | 203 | return 0; |
204 | } | 204 | } |
205 | |||
206 | /** | ||
207 | * Fixed-point natural log | ||
208 | * taken from http://www.quinapalus.com/efunc.html | ||
209 | * "The code assumes integers are at least 32 bits long. The (positive) | ||
210 | * argument and the result of the function are both expressed as fixed-point | ||
211 | * values with 16 fractional bits, although intermediates are kept with 28 | ||
212 | * bits of precision to avoid loss of accuracy during shifts." | ||
213 | */ | ||
214 | |||
215 | long flog(int x) { | ||
216 | long t,y; | ||
217 | |||
218 | y=0xa65af; | ||
219 | if(x<0x00008000) x<<=16, y-=0xb1721; | ||
220 | if(x<0x00800000) x<<= 8, y-=0x58b91; | ||
221 | if(x<0x08000000) x<<= 4, y-=0x2c5c8; | ||
222 | if(x<0x20000000) x<<= 2, y-=0x162e4; | ||
223 | if(x<0x40000000) x<<= 1, y-=0x0b172; | ||
224 | t=x+(x>>1); if((t&0x80000000)==0) x=t,y-=0x067cd; | ||
225 | t=x+(x>>2); if((t&0x80000000)==0) x=t,y-=0x03920; | ||
226 | t=x+(x>>3); if((t&0x80000000)==0) x=t,y-=0x01e27; | ||
227 | t=x+(x>>4); if((t&0x80000000)==0) x=t,y-=0x00f85; | ||
228 | t=x+(x>>5); if((t&0x80000000)==0) x=t,y-=0x007e1; | ||
229 | t=x+(x>>6); if((t&0x80000000)==0) x=t,y-=0x003f8; | ||
230 | t=x+(x>>7); if((t&0x80000000)==0) x=t,y-=0x001fe; | ||
231 | x=0x80000000-x; | ||
232 | y-=x>>15; | ||
233 | return y; | ||
234 | } | ||