"banu" <> wrote in message
news:2f14e97c-fc22-4fdc-abb1-...
> 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