"banu" <(E-Mail Removed)> wrote in message

news:(E-Mail Removed)...

> Hi,

> I tried to google a lot searching for fixed point implementation of

> exponent function y = exp(x) (e to the power x) but could not find it.

> Also I think there is no post on this group also. I found some CORDIC

> implementations but those were in C++. I need lightweight

> implementation in C.

>

> I want to use this function in an image processing algorithm to be

> implemented on a VLIW-DSP which doesn't have a floating point unit.

>

> I will appreciate in anyone here can suggest a plain C - code which

> handles both positive and negative arguments (x<0 and x<=0) ,with

> reasonable accuracy and performance.

>
well, as others have noted, it depends a lot on the number of bits in the

integer and fractional parts.

one possible idea that comes to mind is this:

rebase the exponent into 2^x form (this involves multiplying x by a constant

of 1/ln(2) or about 1.4426950...).

this way, a base can be calculated which is simply an integer power of 2.

then, one only need calculate a scale based on the fractional part, and if

the number of fractional bits is sufficiently small (or memory sufficiently

large), then a lookup table can be used.

then, the 2 numbers can be multiplied together, and one is done.

granted, for larger exponents this strategy may become less accurate. could

be addressed by using a bigger lookup table, or by using a recursive

strategy to calculate the fraction. similarly, some recursion could also

allow a smaller table at the cost of some speed.

another had mentioned using the taylor series, which is also an option, but

not likely as fast as using a lookup table.

for example (hypothetical):

#define FIX12_INVLN2 5909 //1.442695, 12-bit fraction

#define FIX28_INVLN2 387270501 //1.442695, 28-bit fraction

typedef int32_t fix12;

typedef int32_t fix28;

fix12 fix12_mul(fix12 a, fix12 b)

{

return ((fix12)((((int64_t)a)*b)>>12));

}

fix12 fix12_mul28(fix12 a, fix28 b)

{

return ((fix12)((((int64_t)a)*b)>>2

);

}

static fix28 fix12_exp2lut[4096]={...}; //takes ~16kB memory

fix12 fix12_exp2(fix12 x)

{

fix12 b, f;

b=1<<(12+(x>>12)); //calculate base

f=fix12_exp2lut[x&4095];

return(fix12_mul28(b, f));

}

fix12 fix12_exp(fix12 x)

{ return(fix12_exp2(fix12_mul28(x, FIX28_INVLN2))); }

note:

some of the usual optimizations for optimizing fixed point calculations (or

improving accuracy) could possibly also be used here.

> thanks

> varun