Do you have a question? Post it now! No Registration Necessary
posted on
November 21, 2004, 5:11 pm
November 21, 2004, 5:11 pm
Hi,
I am writing a program for a PIC 16f877.
I must calculate some weather parameters and I have need to calculate the
logarithm in base 10.
Exists some formula/procedure that help me to generate a logarithm of a
number between 10 and 100 with only 4 decimal digit?
I know that the result is a real but then I will put it in more byte and
display it.
thanks for the info
stefano
I am writing a program for a PIC 16f877.
I must calculate some weather parameters and I have need to calculate the
logarithm in base 10.
Exists some formula/procedure that help me to generate a logarithm of a
number between 10 and 100 with only 4 decimal digit?
I know that the result is a real but then I will put it in more byte and
display it.
thanks for the info
stefano
Re: logarithm and PIC
I'm not sure if I understand exactly what you're looking for, so I'll
repeat the question back to you and you can correct it if I have
misunderstood. What you want is an approximation of a log10 function
with a maximum error of less than 1e4 over the range (10,100). If
that's correct, then there are a couple of ways to do that. One way
would be to use an series approximation. One that will (mathematically)
meet your requirements is
log10(x) = 0.215228608 + .1362859914*x  0.8941598030e2*x^2 +
0.4317913455e3*x^3  0.1439966989e4*x^4 + 0.3302136507e6*x^5
This has a maximum error of 0.7626633405e4 in the range (10,100) but as
you can see, it's a little complex (and probably quite slow) for a PIC
to calculate. FYI, I generated this approximation in just a couple of
seconds using Maple. (see http://www.maplesoft.com ) Specifically, I
used the minimax function, but there are other means of turning
trancendental functions into series approximations, e.g Chebyshev, (see
http://mathworld.wolfram.com/ChebyshevApproximationFormula.html ) and
and PadeChebyshev. (see
http://mathworld.wolfram.com/ChebyshevApproximationFormula.html and
links). If you find calculus scary, don't look! :)
The more usual method is to use a table lookup. Since you need so much
precision, you'll have to use a table and interpolation. Conceptually,
this is done by approximating the curve as a series of straight lines,
and there are a couple of ways to "slice" the curve. One way is to
divide up the curve at equally spaced intervals, and another way is to
divide up the curve so that the straight line approximation between the
two points is less than or equal to your desired error term. You might
do it the first way to save on lookup time at the expense of ROM table
size or the second way to economize a little on ROM at the expense of
lookup time. (In some circumstances that require less precision than
yours, you can use just a simple lookup.)
You can create the tables yourself with a simple program on your desktop
machine. How you do it depends on a lot of things, not least of which
is the number representation you decide to use in the PIC. Obvious
options include fixed point and floating point, but floating point on a
PIC is going to be painful if you haven't done this kind of thing before.
If this explanation doesn't help, try asking again with a little more
detail.
Ed
Re: logarithm and PIC
 clip clip 
In a binary computer, the logarithm is often easier to
calculate in base 2, so only the interval (1,2) needs
to be considered. The number is normalized into the
interval by plain bit shifts, and the shift count
remembered. The shift count is the integer part of
base 2 logarithm to be added to the tabulated/interpolated
result.
In any case, logarithm is the most complicated elementary
function to calculate from a series.
Which format are your input data in?
For integers, by far the easiest way is a table
with all the entries in the range you're interested,
even though a constant table is a kind of PITA
in a PIC.

Tauno Voipio
tauno voipio (at) iki fi
Tauno Voipio
tauno voipio (at) iki fi
Re: logarithm and PIC
>
> In any case, logarithm is the most complicated elementary
> function to calculate from a series.
>
> Which format are your input data in?
>
> For integers, by far the easiest way is a table
> with all the entries in the range you're interested,
> even though a constant table is a kind of PITA
> in a PIC.
>

my data is integer with range from 10..100

you have reason, only now i have understood that calculate the logarithms
with series it is much complicated , I will have to reserve 90 cells of
memory in order to insert the logarithms table
A very small price to pay as compared to having to try to actually compute it
BTW I don't think 8 bits gives you the precision you require. You'll need
a miniumum of 14 bits to get down to 1/10000 resolution.
BAJ
> In any case, logarithm is the most complicated elementary
> function to calculate from a series.
>
> Which format are your input data in?
>
> For integers, by far the easiest way is a table
> with all the entries in the range you're interested,
> even though a constant table is a kind of PITA
> in a PIC.
>

my data is integer with range from 10..100

you have reason, only now i have understood that calculate the logarithms
with series it is much complicated , I will have to reserve 90 cells of
memory in order to insert the logarithms table
A very small price to pay as compared to having to try to actually compute it
BTW I don't think 8 bits gives you the precision you require. You'll need
a miniumum of 14 bits to get down to 1/10000 resolution.
BAJ
Re: logarithm and PIC
You're absolutely right. Apparently a cutandpaste error. My
apologies! Here's a correct form:
f(x) :=
.2152286561+(.1362859746+(0.8941595723e2+(0.4317911768e3+(0.1439966252e4+(0.3302134471e6+(0.5177507477e8+(0.5440287309e10+(0.3656629823e12+(0.1419115613e140.2416529628e17*x)*x)*x)*x)*x)*x)*x)*x)*x)*x
It's also in a form that's a bit easier for a computer to use.
However, I see that in another message you say that your inputs are
integers. If that's the case and the range is only 10100, you are
definitely better off using a table! Here's a table version in C
showing the values and also the approximate error terms which should all
be less than 1e4.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
short int log10table[] = {
0x0000,0x0A98,0x1445,0x1D2B,0x2568,0x2D14,0x3441,0x3AFE,
0x4159,0x475C,0x4D10,0x527C,0x57A9,0x5C9A,0x6155,0x65DF,
0x6A3B,0x6E6D,0x7278,0x765F,0x7A24,0x7DC9,0x8151,0x84BD,
0x880F,0x8B48,0x8E69,0x9175,0x946C,0x9750,0x9A20,0x9CDF,
0x9F8D,0xA22A,0xA4B9,0xA738,0xA9AA,0xAC0E,0xAE65,0xB0B0,
0xB2EF,0xB523,0xB74B,0xB96A,0xBB7E,0xBD88,0xBF89,0xC181,
0xC370,0xC556,0xC734,0xC90B,0xCADA,0xCCA1,0xCE61,0xD01B,
0xD1CD,0xD379,0xD51F,0xD6BE,0xD858,0xD9EC,0xDB7A,0xDD02,
0xDE85,0xE004,0xE17C,0xE2F1,0xE460,0xE5CA,0xE730,0xE892,
0xE9EF,0xEB48,0xEC9D,0xEDEE,0xEF3B,0xF084,0xF1C9,0xF30B,
0xF449,0xF583,0xF6BA,0xF7EE,0xF91E,0xFA4C,0xFB76,0xFC9D,
0xFDC0,0xFEE1,0xFFFF
};
int main()
{
int i;
double x;
for (i10%; i < 101; i++)
{
x = 1.0 + (log10table[i10]/65536.0);
if (i > 31) x = x + 1.0;
printf("%d\t%f\t%g\n", i, x, log10(i)x);
}
return 0;
}
There are ways to optimize this, of course, but this should get you
started with something that works. Also, in the real code, don't forget
about range checking! You don't want to go off the end of the table.
Ed
Re: logarithm and PIC
 One way
 would be to use an series approximation. One that will (mathematically)
 meet your requirements is

 log10(x) = 0.215228608 + .1362859914*x  0.8941598030e2*x^2 +
 0.4317913455e3*x^3  0.1439966989e4*x^4 + 0.3302136507e6*x^5
This equation can be reduced to 0.215228608 + x*(0.1362859914 
x*(0.894159803e2  x*(0.4317913455e3  x*(0.1439966989e4 
x*(0.3302136507e6)))))
This reduces the number of multiplications from 9 to 5.
 would be to use an series approximation. One that will (mathematically)
 meet your requirements is

 log10(x) = 0.215228608 + .1362859914*x  0.8941598030e2*x^2 +
 0.4317913455e3*x^3  0.1439966989e4*x^4 + 0.3302136507e6*x^5
This equation can be reduced to 0.215228608 + x*(0.1362859914 
x*(0.894159803e2  x*(0.4317913455e3  x*(0.1439966989e4 
x*(0.3302136507e6)))))
This reduces the number of multiplications from 9 to 5.

MT
To reply directly, please first take your dick out of my address.
MT
To reply directly, please first take your dick out of my address.
Re: logarithm and PIC
Jack Crenshaw had an article on a clever way of calculating a base2
logarithm in the March 1998 issue of Embedded Systems Programming. Also
in his "Math Toolkit for RealTime Programming" (ISBN 1929629095).
There are a few descriptions online; google for "Crenshaw bitlog".

Rich Webb Norfolk, VA
Rich Webb Norfolk, VA
Re: logarithm and PIC
Keep in mind that a straight lookup table has almost no code, plus if
you intend to display the result you can put the final display values
in the table. If you implement a log10 algorithm it has to be smaller
than a 90 element table (you did later say the input was integer, right?)
if you want to save space.

Ben Jackson
Ben Jackson
We've slightly trimmed the long signature. Click to see the full one.
Site Timeline
 » Reverse current into a lithium battery
 — Next thread in » Embedded Programming
 » Philips 89C66X
 — Previous thread in » Embedded Programming
 » what's the startup clock frequency of PIC1703
 — Newest thread in » Embedded Programming
 » Come far 'parlare' scheda elettronica con smartphone?
 — The site's Newest Thread. Posted in » Electronics Hobby (Italian)
 » 64 bits, a reprise
 — The site's Last Updated Thread. Posted in » Raspberry Pi Group