DSPRelated.com
Forums

Question on fixed point division

Started by philfuxx August 23, 2005
Hi all,

I'm new to DSP programming. So far my asm program works fine on TI's
TMS320LF2407 DSP. However, I have to extend my program and need to
divide two 10 bit integer numbers (a, b) which are not related to each
other and change over time (they're obtained through 2 ch AD
conversion).
In most cases b > a. Does anyone know a simple algorithm to compute the
result x = a/b? The DSP provides only add, sub and multiplication
(signed/unsigned).

Moreover I want to compute the Taylor series for

ln(1-x) = x - x^2/2 + x^3/3 - ...

Here, I encounter the same difficulties: how to perform the division of
each summand? I need it to simplify to multiplication and
addition/subtraction that the fixed point dsp can handle.
BTW: I know that a look-up table is the easiest way to compute the ln
of some numbers. But the range is relatively wide and memory
consumption is an issue.

I appreciate any help!

Regards,

Arno

philfuxx wrote:
> Hi all, > > I'm new to DSP programming. So far my asm program works fine on TI's > TMS320LF2407 DSP. However, I have to extend my program and need to > divide two 10 bit integer numbers (a, b) which are not related to each > other and change over time (they're obtained through 2 ch AD > conversion). > In most cases b > a. Does anyone know a simple algorithm to compute the > result x = a/b? The DSP provides only add, sub and multiplication > (signed/unsigned). > > Moreover I want to compute the Taylor series for > > ln(1-x) = x - x^2/2 + x^3/3 - ... > > Here, I encounter the same difficulties: how to perform the division of > each summand? I need it to simplify to multiplication and > addition/subtraction that the fixed point dsp can handle. > BTW: I know that a look-up table is the easiest way to compute the ln > of some numbers. But the range is relatively wide and memory > consumption is an issue. > > I appreciate any help! > > Regards, > > Arno >
Does that processor not have a divide primitive? The '28xx does. The only way I know to do it on a processor like that is by good old long division -- subtract the divisor from the dividend, add a '1' into the answer if the remainder is positive, don't if it isn't, shift and repeat as necessary. In fact, that's what the divide primitive does, it just does 1 bit of quotient each iteration, so you can decide on your desired level of precision and loop that many times. I believe that the taylor's series is going to converge very slowly for logarithms. In a DSP, assuming you have the memory, the way to go there is with a multiply-and-accumulate, with fixed coefficients. You may find yourself using less code space with the coefficient vector than you would with the code. For ln I'd prescale the numbers -- actually for ln I'd take the log to the base two (to make prescaling really easy) then I'd only have to come up with enough precision for logs of numbers between 0.5 and 1. -- Tim Wescott Wescott Design Services http://www.wescottdesign.com
Hi Tim,

I think you mean something like this:

http://www.emesystems.com/division.htm

I didn't know that there's a divide primitive. But I'll look for that
in code composer. Hopefully, it is not only for "C".


Yes, it seems to be a better choice to store some coefficients and use
base-2. However, I'm not quite sure in which way I should prescale the
coefficients.

in article 11gmdrqiapkas6a@corp.supernews.com, Tim Wescott at
tim@seemywebsite.com wrote on 08/23/2005 10:49:

> philfuxx wrote: >> >> Moreover I want to compute the Taylor series for >> >> ln(1-x) = x - x^2/2 + x^3/3 - ... >> >> Here, I encounter the same difficulties: how to perform the division of >> each summand?
no need to divide, if you compute these coefficients in advance
> > I believe that the taylor's series is going to converge very slowly for > logarithms. In a DSP, assuming you have the memory, the way to go there > is with a multiply-and-accumulate, with fixed coefficients. You may > find yourself using less code space with the coefficient vector than you > would with the code. For ln I'd prescale the numbers -- actually for ln > I'd take the log to the base two (to make prescaling really easy) then > I'd only have to come up with enough precision for logs of numbers > between 0.5 and 1.
or between 1 and 2. since Arno isn't gonna add up an infinite Taylor series, he/she has to truncate it somewhere and in that case there are better (more optimally computed) choices of coefficients. of course, what is being computed is an approximation to the log or whatever function. for an optimized finite series of 6th order log2(), check out http://groups.google.com/group/comp.dsp/msg/8ba6bd6fe2474876 . -- r b-j rbj@audioimagination.com "Imagination is more important than knowledge."
On 23 Aug 2005 07:14:59 -0700, "philfuxx" <ArnoKromke@gmx.de> wrote:


>Moreover I want to compute the Taylor series for > >ln(1-x) = x - x^2/2 + x^3/3 - ...
This is easy. Division by a number is equivalent to multiplying with its reciprocal, which can be precomputed. Mit freundlichen Gr&#4294967295;&#4294967295;en Frank-Christian Kr&#4294967295;gel
Here's my 2 cents.

To do a divide, first code it up in C, and check the lst file to see
what the compiler generated.  The compiler may inject the code
directly, or it may call a function.  I think Code Composer includes
the source code for all the functions.

Another approach that is efficient is the method used by the Sharc
processors.  What you want to do is compute 1/b and then multiply by a.
 To compute 1/b, use b to go into a short lookup table, and then
iterate on it a couple of times.  You can look at the Sharc RECIPS
instruction.

Tim Wescott wrote:
> philfuxx wrote: > >> Hi all, >> >> I'm new to DSP programming. So far my asm program works fine on TI's >> TMS320LF2407 DSP. However, I have to extend my program and need to >> divide two 10 bit integer numbers (a, b) which are not related to each >> other and change over time (they're obtained through 2 ch AD >> conversion). >> In most cases b > a. Does anyone know a simple algorithm to compute the >> result x = a/b? The DSP provides only add, sub and multiplication >> (signed/unsigned). >> >> Moreover I want to compute the Taylor series for >> >> ln(1-x) = x - x^2/2 + x^3/3 - ... >> >> Here, I encounter the same difficulties: how to perform the division of >> each summand? I need it to simplify to multiplication and >> addition/subtraction that the fixed point dsp can handle. >> BTW: I know that a look-up table is the easiest way to compute the ln >> of some numbers. But the range is relatively wide and memory >> consumption is an issue. >> >> I appreciate any help! >> >> Regards, >> >> Arno >> > Does that processor not have a divide primitive? The '28xx does. The > only way I know to do it on a processor like that is by good old long > division -- subtract the divisor from the dividend, add a '1' into the > answer if the remainder is positive, don't if it isn't, shift and repeat > as necessary. In fact, that's what the divide primitive does, it just > does 1 bit of quotient each iteration, so you can decide on your desired > level of precision and loop that many times. > > I believe that the taylor's series is going to converge very slowly for > logarithms. In a DSP, assuming you have the memory, the way to go there > is with a multiply-and-accumulate, with fixed coefficients. You may > find yourself using less code space with the coefficient vector than you > would with the code. For ln I'd prescale the numbers -- actually for ln > I'd take the log to the base two (to make prescaling really easy) then > I'd only have to come up with enough precision for logs of numbers > between 0.5 and 1.
There is a floating-point algorithm for division on multiply-only DSPs that computes the reciprocal iteratively, then multiplies. I could look it up, but I don't want to quote it from memory. Jerry -- Engineering is the art of making what you want from things you can get. &#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;
Hi Jerry,

I'm interested in that floating-point algorithm for division on
multiply only DSPs. If you don't mind, then post it here.

Thanks,

Arno

Hey Dan,

this is definitely a good idea to see what the compiler does. I'm gonna
code the division part in C ...

-Arno

Hi Frank-Christian,

I just don't see the solution ...

Yeah okay: x / (a/b) = x * (b/a) now I plug some numbers in:

and obviouly: 4 / (3/5) = 4 * (5/3).

Does this really change anything? It's getting too late, I just can't
think. I'm gonna hit the hay.

Guten Nacht ...

Arno