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