Date: 19981216
From: Onestone
Organization: Digital Voodoo
To: Mot-68HC11-Apps@freeware.mcu.motsps.com [Outdated address, see ../chipdir/ml/proc.htm]
Subject: Re: Log calculation...
Dominic Cayen wrote:
>
> Message sent by "Dominic Cayen"
> to the mot-68hc11-apps Mailing List.
>
> Hello list,
>
> I need to calculate a logarithmic value with the HC12. So far I
> have 2 possible solutions. The first one is the math11.asm from
> Motorola that is capable of doing floating point and log
> calculation. The problem with this solution is that it+IBk-s that
> the code is going to be used in our product (copyright) and
> second it+IBk-s a big file to include in the HC12 memory.
>
> The second solution is a lookup table. For our product I need to
> be able to convert value from mW to dBm. The full range is
> from +IBM-40dBm to +-30dBm. This gives a lot of value in the table
> even if I increment the low end of the range by 0.5dBm. The high
> end has to be in at least 0.1dBm.
>
> I would like to know what is the best way to go. (I think lookup
> is better)
>
> Any suggestion would be appreciated. I just want to learn from
> your experience.
>
> Thanks
>
Dominic, from "DIGITAL SIGNAL PROCESSING APPLICATIONS USING THE
ADSP-2100 FAMILY" by Analog Devices.
'the common logarithm (base ten) of a number x between one and two can
be approximated using the following equation:
2log10(x) = 0.8678284(x-1) - 0.4255677(x1-)^2 + 0.2481384(x-1)^3 -
0.1155701(x-1)^4 + 0.0272522(x-1)^5'
It goes on to state that numbers greater than 2 or less than 1 have to
be scaled. The format used for the input number is 16.16. This is 16
bits of binary fraction and a 16 bit integer. They describe a scaling
method which shifts the 16.16 value essentially to produce a number in
the range 0001.0000h to 0001.1111h after first removing any redundant
sign bits. They then describe the adjustement to the logarithm, to
compensate for scaling as :
Y = log(X)
Z = log(sX)
log(sX) = log(s) + log(X)
Y = Z - log(s)
Hence the logarithm of the unscaled input is equal to the logarithm of
the scaled input less the logarithm of the scaling factor s. Computation
of log(s) is simplified by the fact that s is a power of 2.
s = 2^(se+14)
log(s) = log(2^(se+14)) = (se+14)log(2).
A routine is given in ADSP assembler, which computes natural and common
logs. It takes 33 cycles on an ADSP2100, but looks easy enough to
implement on a HC12.
I don't want to teach you to suck eggs, and assume that since you know
the HC12 you are familiar with FDIV and binary fractions, as well as
doing math with them.
--
Cheers From
Al @
Digital Voodoo
*** Gravity is a myth. The Earth sucks ***
Date: Thu, 26 Jul 2001 15:51:54 -0800
From: Tom Harrold
To: Multiple recipients of list CHIPDIR-L
Subject: Math problem
Hi list members,
I am looking for an equation that will do the reverse function of exponents.
Like NOT 10**p. i.e.:
if given a number 9,200.0 to the equation, I expect the answer is 3 or
1,000.0... Then next time I give a different number like: 843.0 and I expect
the number is 2 or 100.0... and so on...
Thanks!
TH
Date: Thu, 26 Jul 2001 22:30:24 -0800
From: Uwe Zimmermann
To: Multiple recipients of list CHIPDIR-L
Subject: Re: Math problem
the inverse functions of exponential functions are logarithmic
functions:
log10(10^x) = x
log(exp(x)) = x
log10( 1) = 0
log10( 10) = 1
log10( 100) = 2
log10( 532) = 2.726
log10(1000) = 3
...
on calculators "log" is often called "ln" (logarithmus naturalis) and
"log10" "log".
Uwe.
Tom Harrold wrote:
>
> Hi list members,
> I am looking for an equation that will do the reverse function of exponents.
> Like NOT 10**p. i.e.:
> if given a number 9,200.0 to the equation, I expect the answer is 3 or
> 1,000.0... Then next time I give a different number like: 843.0 and I expect
> the number is 2 or 100.0... and so on...
> Thanks!
> TH
Date: Fri, 27 Jul 2001 11:17:04 -0800
From: Jaap van Ganswijk
To: Multiple recipients of list CHIPDIR-L
Subject: Re: Math problem
At 2001-07-26 22:30 -0800, Uwe Zimmermann wrote:
>the inverse functions of exponential functions are logarithmic
>functions:
>
>log10(10^x) = x
>log(exp(x)) = x
>
>
>log10( 1) = 0
>log10( 10) = 1
>log10( 100) = 2
>log10( 532) = 2.726
>log10(1000) = 3
Yes, and anylog(a*b)=anylog(a)+anylog(b).
This is how multiplication was done on a slide ruler
(Dutch: rekenliniaal). The scales were logarithmic
so multiplication became addition.
>on calculators "log" is often called "ln" (logarithmus naturalis) and
>"log10" "log".
Yes, ln is the e-log, with e being about 2.718281828
By the way, p-log(n) = anylog(n)/anylog(p), so you can still
calculate the 3-log on a calculator with only log10 or ln.
Greetings,
Jaap
Date: Fri, 27 Jul 2001 11:27:38 -0800
From: Bob Smith
To: Multiple recipients of list CHIPDIR-L
Subject: Re: Math problem
As usual, Uwe has addressed this question in his very professional
style. I have nothing to add except to mention a minor problem that I
have sometimes encountered.
On a few ocassions, I have encountered systems that will only return the
natural logarithm of an unknown when I desire the logarithm base 10 (for
example). In these cases it is useful to remember that to convert from
a logarithm in a given base to one in a different base one simply has to
multiply by a constant.
The general law is:
log base a (x) = log base b (x) / log base b (a) = log base b (x) * (log
base a (b)
As an example (and using Uwe's notation) the most common problem that I
have encountered is having only the natural log available when I desire
results in log base 10.
log10(x) = log(x) / log(10) = log10(e) * log(x) = 0.43429 4481819
log(x)
One normally has to pre-calculate the constant of conversion using a
more general purpose calculator/math package and store the result in his
program as a constant.
Bob Smith
Uwe Zimmermann wrote:
>
> the inverse functions of exponential functions are logarithmic
> functions:
>
> log10(10^x) = x
> log(exp(x)) = x
>
> log10( 1) = 0
> log10( 10) = 1
> log10( 100) = 2
> log10( 532) = 2.726
> log10(1000) = 3
> ...
>
> on calculators "log" is often called "ln" (logarithmus naturalis) and
> "log10" "log".
>
> Uwe.
>
> Tom Harrold wrote:
> >
> > Hi list members,
> > I am looking for an equation that will do the reverse function of exponents.
> > Like NOT 10**p. i.e.:
> > if given a number 9,200.0 to the equation, I expect the answer is 3 or
> > 1,000.0... Then next time I give a different number like: 843.0 and I expect
> > the number is 2 or 100.0... and so on...
> > Thanks!
> > TH
--
--------- Avoid computer viruses -- Practice safe hex -------------
* * Specializing in small, cost effective embedded control systems * *
Robert L. (Bob) Smith Smith Machine Works, Inc.
Date: Sat, 28 Jul 2001 01:18:08 -0800
From: Matthias Weingart
To: Multiple recipients of list CHIPDIR-L
Subject: Re: Math problem
And now the easy way. From your mail I can see, that you only want a integer
result; simply divide your number multiple times by 10, count how often
and
you get the number of digits (or roughly the log(x) ).
int
log(int input)
{
int i=0;
while (input>10) {
i++;
input/=10;
}
return i;
}
M.
Date: Sat, 28 Jul 2001 10:10:18 -0800
From: Uwe Zimmermann
To: Multiple recipients of list CHIPDIR-L
Subject: Re: Math problem
...and you think in times of built-in floating point units in the
processor that is the easy way?
ans=int(log(x)/log(10));
is not only shorter but probably also much faster than multiple
divisions in a loop....
In order to avoid the calculation of the second log you can give the
constant from the beginning (an intelligent compiler would do so
anyway) and write
ans=int(log(x)/2.3026);
now not trusting floating point divisions on Pentium processors you
can also write
ans=int(0.4343*log(x));
Just my two cents...
Uwe.
Matthias Weingart wrote:
>
> And now the easy way. From your mail I can see, that you only want a integer
> result; simply divide your number multiple times by 10, count how often and
> you get the number of digits (or roughly the log(x) ).
>
> int log(int input)
> {
> int i=0;
> while (input>10)
> {
> i++;
> input/=10;
> }
> return i;
> }
--
Author: Uwe Zimmermann
Date: Sat, 28 Jul 2001 11:35:18 -0800
From: Matthias Weingart
To: Multiple recipients of list CHIPDIR-L
Subject: Re: Math problem
On Sat, Jul 28, 2001 at 10:10:18AM -0800, Uwe Zimmermann wrote:
> ...and you think in times of built-in floating point units in the
> processor that is the easy way?
Well sure, but he did not tell us, for what processor he needs it. For a
Z80, 8051, and other embedded controllers, log() is more expensive as div().
M.
--
Author: Matthias Weingart
Date: Sat, 28 Jul 2001 11:55:21 -0800
From: Uwe Zimmermann
To: Multiple recipients of list CHIPDIR-L
Subject: Re: Math problem
Matthias Weingart wrote:
>
> On Sat, Jul 28, 2001 at 10:10:18AM -0800, Uwe Zimmermann wrote:
> > ...and you think in times of built-in floating point units in the
> > processor that is the easy way?
>
> Well sure, but he did not tell us, for what processor he needs it. For a
> Z80, 8051, and other embedded controllers, log() is more expensive as div().
>
that of course is true - however on a pure integer system the integer
log2 i.e. the log on the base of 2 is even easier to realize since
even div might be "expensive" on these. It would be the number of the
highest bit set in the input number and from there you come to the
log10 by multiplying the result by log10(2)=0.3010
e.g.
x=256
highest bit number is 8=int(log2(256))
log10(256)=2.4082 is approx 0.3010*8=2.4080
or even
int(log10(256) = int(0.3010'8) = 2
Uwe.
--
Author: Uwe Zimmermann
Date: Sat, 28 Jul 2001 12:15:28 -0800
From: Bob Smith
To: Multiple recipients of list CHIPDIR-L
Subject: OT: Re: Math problem
Uwe --
You seem to be very well versed in these matters.
Can you comment a bit on the meaning of the value of e?
Most of the irrational numbers one encounters in engineering seem to
have some basis in real life, geometry, or trigonometry. I.E. Pi, the
common trig functions, Golden Ratio, etc.
But what does e relate to????
Thanks, Bob Smith
Uwe Zimmermann wrote:
>
> ...and you think in times of built-in floating point units in the
> processor that is the easy way?
>
> ans=int(log(x)/log(10));
>
> is not only shorter but probably also much faster than multiple
> divisions in a loop....
> In order to avoid the calculation of the second log you can give the
> constant from the beginning (an intelligent compiler would do so
> anyway) and write
>
> ans=int(log(x)/2.3026);
--
--------- Avoid computer viruses -- Practice safe hex -------------
* * Specializing in small, cost effective embedded control systems * *
Robert L. (Bob) Smith Smith Machine Works, Inc.
Date: Sat, 28 Jul 2001 12:25:23 -0800
From: Jaap van Ganswijk
To: Multiple recipients of list CHIPDIR-L
Subject: Re: Math problem
At 2001-07-28 11:35 -0800, Matthias Weingart wrote:
>On Sat, Jul 28, 2001 at 10:10:18AM -0800, Uwe Zimmermann wrote:
>> ...and you think in times of built-in floating point units in the
>> processor that is the easy way?
>
>Well sure, but he did not tell us, for what processor he needs it. For a
>Z80, 8051, and other embedded controllers, log() is more expensive as div().
Lots of guessing going on... ;-)
Perhaps he can also use the log2(). That way the division operation
is a simple inexpensive shift, with often a build in compare with zero.
So something like:
label
inc counter
shr number
jne label
And this can even be speeded up by using:
if (number>=0x100) {
counter=8;
number>>=8;
}
else {
counter=0;
}
I seem to remember vaguely that there is even a faster
method to determine the number of needed shifts using
XOR in some way.
Or he can use a table lookup when only say 10 bit values
need to be converted.
Unless the problem is defined more closely it's hard to determine the
best solution...
Greetings,
Jaap
Date: Sat, 28 Jul 2001 13:10:19 -0800
From: Uwe Zimmermann
To: Multiple recipients of list CHIPDIR-L
Subject: Re: OT: Re: Math problem
Bob Smith wrote:
>
> Uwe --
>
> You seem to be very well versed in these matters.
> Can you comment a bit on the meaning of the value of e?
> Most of the irrational numbers one encounters in engineering seem to
> have some basis in real life, geometry, or trigonometry. I.E. Pi, the
> common trig functions, Golden Ratio, etc.
>
> But what does e relate to????
e is perhaps the most basic and important irrational number of all,
but it is a bit more hidden to the eye than e.g. pi.
e is even related directly to pi, but for this to see you have to go
to the plane of complex numbers first.
First to the plain "e", the Eulerian number.
The number "e" can be derived from the following infinite sum
e=1/1! + 1/2! + 1/3! + 1/4! +...+ 1/n! + ...
with n!=1*2*3*..*n
or as an approximation
e=0;
for i=1 to n
dummy=1;
for j=1 to i
dummy=dummy*j;
end
e=e+dummy;
end
In any growth or decay process where the increase/decay at a certain
timestep is depended on the amount still/already there just at this
timestep can be described by the exponential function based on "e":
Lets take the growth of bacteria as an example. Each bacteria
increases the population by duplication after a certain time \tau. If
we start at time t=0 with n=1 one bacteria we'll have n=2 after
t=\tau, n=4 after t=2*\tau and so on.
the change in population delta_n(t) is proportional to n(t)
delta_n(t) = k*n(t)
If you see n(t) as a function, the change delta_n(t) corresponds to
the first derivative of this function and this leads to a so-called
differential equation of the form
dn/dt = k*n(t)
now there is only one function which fulfills the criterion that its
first derivative is the function itself multiplied by a constant - the
exponential function with "e" as base f(x)=e^x or f(x)=exp(x)
and therefore this is the solution to the above problem with
n(t) =exp(k*t)
dn/dt=k*exp(k*t)=k*n(t)
More general all of the above mentioned growth processes can be
described by this function with a problem specific growth rate
constant k and a start value for t=0
y(t) = y(t=0) * exp(k*t)
If k is a negative number this function describes a decay, like the
discharge of a capacitor through a resistor
U(t) = U(t=0) * exp(-1/(RC)*t)
or the charging of a capacitor from a constant voltage source through
a resistor
U(t) = U * (1 - exp(-1/(RC)*t))
Now - to end this for now (to be continued if whished for)
If you have a look at complex numbers, a new constant i or j is
introduced which is equal to the square root of (-1) per definition.
This is not a number you can write down in any way as a decimal or
rational or irrational number.
In the complex plane every number is a point with two coordinates, one
real and one imaginary
a = ar + i*ai
ar = Real(a)
ai = Imaginary(a)
In this plane the exponential function circulates around the origin
when you allow a purely imaginary argument:
exp(0) = 1 + 0*i
exp(i*pi/2) = 0 + 1*i
exp(i*pi) =-1 + 0*i
exp(i*2*pi) = 0 - 1*i
and cosine and sine can be written as exponential functions with a
real argument x:
cos(x) = 0.5 * (exp(i*x) + exp(-i*x))
sin(x) = 0.5 * i * (exp(i*x) - exp(-i*x))
There is much more, but perhaps not today....
Uwe.
--
Author: Uwe Zimmermann
Date: Sat, 28 Jul 2001 14:05:19 -0800
From: Bob Smith
To: Multiple recipients of list CHIPDIR-L
Subject: Re: OT: Re: Math problem
Uwe --
Thank you, thank you! You have shined a light as brilliant as the
rising Sun in to one of the dark corners of my mind.
I should have recognized this from the Transient Circuit chapter of
EE101, but that was 40+ years back. Dumb!!!!!
I think that lesson will do for today.
Many thanks, Bob Smith
Uwe Zimmermann wrote:
>
> Bob Smith wrote:
> >
> > Uwe --
> >
> > You seem to be very well versed in these matters.
> > Can you comment a bit on the meaning of the value of e?
> > Most of the irrational numbers one encounters in engineering seem to
> > have some basis in real life, geometry, or trigonometry. I.E. Pi, the
> > common trig functions, Golden Ratio, etc.
> >
> > But what does e relate to????
>
> e is perhaps the most basic and important irrational number of all,
> but it is a bit more hidden to the eye than e.g. pi.
> e is even related directly to pi, but for this to see you have to go
> to the plane of complex numbers first.
>
> First to the plain "e", the Eulerian number.
>
> The number "e" can be derived from the following infinite sum
> e=1/1! + 1/2! + 1/3! + 1/4! +...+ 1/n! + ...
>
> with n!=1*2*3*..*n
>
> or as an approximation
> e=0;
> for i=1 to n
> dummy=1;
> for j=1 to i
> dummy=dummy*j;
> end
> e=e+dummy;
> end
>
> In any growth or decay process where the increase/decay at a certain
> timestep is depended on the amount still/already there just at this
> timestep can be described by the exponential function based on "e":
>
> Lets take the growth of bacteria as an example. Each bacteria
> increases the population by duplication after a certain time \tau. If
> we start at time t=0 with n=1 one bacteria we'll have n=2 after
> t=\tau, n=4 after t=2*\tau and so on.
>
> the change in population delta_n(t) is proportional to n(t)
>
> delta_n(t) = k*n(t)
>
> If you see n(t) as a function, the change delta_n(t) corresponds to
> the first derivative of this function and this leads to a so-called
> differential equation of the form
>
> dn/dt = k*n(t)
>
> now there is only one function which fulfills the criterion that its
> first derivative is the function itself multiplied by a constant - the
> exponential function with "e" as base f(x)=e^x or f(x)=exp(x)
>
> and therefore this is the solution to the above problem with
>
> n(t) =exp(k*t)
>
> dn/dt=k*exp(k*t)=k*n(t)
>
> More general all of the above mentioned growth processes can be
> described by this function with a problem specific growth rate
> constant k and a start value for t=0
>
> y(t) = y(t=0) * exp(k*t)
>
> If k is a negative number this function describes a decay, like the
> discharge of a capacitor through a resistor
>
> U(t) = U(t=0) * exp(-1/(RC)*t)
>
> or the charging of a capacitor from a constant voltage source through
> a resistor
>
> U(t) = U * (1 - exp(-1/(RC)*t))
>
> Now - to end this for now (to be continued if whished for)
> If you have a look at complex numbers, a new constant i or j is
> introduced which is equal to the square root of (-1) per definition.
> This is not a number you can write down in any way as a decimal or
> rational or irrational number.
> In the complex plane every number is a point with two coordinates, one
> real and one imaginary
>
> a = ar + i*ai
>
> ar = Real(a)
> ai = Imaginary(a)
>
> In this plane the exponential function circulates around the origin
> when you allow a purely imaginary argument:
>
> exp(0) = 1 + 0*i
> exp(i*pi/2) = 0 + 1*i
> exp(i*pi) =-1 + 0*i
> exp(i*2*pi) = 0 - 1*i
>
> and cosine and sine can be written as exponential functions with a
> real argument x:
>
> cos(x) = 0.5 * (exp(i*x) + exp(-i*x))
> sin(x) = 0.5 * i * (exp(i*x) - exp(-i*x))
>
> There is much more, but perhaps not today....
>
> Uwe.
> --
> Author: Uwe Zimmermann
Robert L. (Bob) Smith Smith Machine Works, Inc.
Date: Sun, 29 Jul 2001 00:45:19 -0800
From: Tom Harrold
To: Multiple recipients of list CHIPDIR-L
Subject: Re: Math problem
To Mat,
Thank you, but my whole idea was to stay-away from loops.
So, I got my answer...
In Turbo C/C++ ver 3.0:
#include
double *power(double f)
{
int i;
return pow10(modf(log10(f),&i) - log10(f));
}
----- Original Message -----
To: Multiple recipients of list CHIPDIR-L
Sent: Saturday, July 28, 2001 2:18 AM
> > Tom Harrold wrote:
> > >
> > > Hi list members,
> > > I am looking for an equation that will do the reverse function of
exponents.
> > > Like NOT 10**p. i.e.:
> > > if given a number 9,200.0 to the equation, I expect the answer is 3 or
> > > 1,000.0... Then next time I give a different number like: 843.0 and I
expect
> > > the number is 2 or 100.0... and so on...
> > > Thanks!
> > > TH
>
> And now the easy way. From your mail I can see, that you only want a
integer
> result; simply divide your number multiple times by 10, count how often
and
> you get the number of digits (or roughly the log(x) ).
>
> int log(int input)
> {
> int i=0;
> while (input>10)
> {
> i++;
> input/=10;
> }
> return i;
> }
>
> M.
> --
> Author: Matthias Weingart
Author: Tom Harrold