Does anyone know of a good C math library for 8 bit PICs (PIC16F
type)? The ones HI-TECH C provides are a bit strange. The sine values
that the sin function calculates are a bit off. My calculators and
computers are all giving the right answer, but the HI-TECH library is
only accurate to about three decimal places. After that, the numbers
don't match my calculator and my computer. I looked at the source code
for sine and it *looks* like they're using the CORDIC algorithm. I
thought that (after reading various articles on the Internet) that
most calculators use CORDIC to compute sine. So shouldn't my
calculator and HI-TECH be giving the same answer? I'm building a
calculator, so I want my math functions to be giving the right values.
If anyone has any answers to explain this anomaly or any links to
other math libraries, I would really appreciate it.
I tried to look through uClibc but their library is HUGE and designed
for 32 bit architectures I believe. It would take wayyyyy too long to
strip out the useful bits from their library. Same with other
libraries I've looked at.
"solarwind" wrote:
> Does anyone know of a good C math library for 8 bit PICs (PIC16F
> type)? The ones HI-TECH C provides are a bit strange. The sine values
> that the sin function calculates are a bit off. My calculators and
> computers are all giving the right answer, but the HI-TECH library is
> only accurate to about three decimal places. After that, the numbers
> don't match my calculator and my computer. I looked at the source code
> for sine and it *looks* like they're using the CORDIC algorithm. I
> thought that (after reading various articles on the Internet) that
> most calculators use CORDIC to compute sine. So shouldn't my
> calculator and HI-TECH be giving the same answer? I'm building a
> calculator, so I want my math functions to be giving the right values.
>
> If anyone has any answers to explain this anomaly or any links to
> other math libraries, I would really appreciate it.
>
> I tried to look through uClibc but their library is HUGE and designed
> for 32 bit architectures I believe. It would take wayyyyy too long to
> strip out the useful bits from their library. Same with other
> libraries I've looked at.
You know why I'm happy? This is totally off topic but I was so pissed
off two days ago cuz I thought I broke my HD44780 LCD. Then today I
noticed my potentiometer was BROKEN so the LCD wasn't damaged, it was
just that I couldn't see anything on it due to no contrast adjustment.
Now I plugged in a new potentiometer and snapped in my HD44780 module
in and it works again. I'm weird that way...
Anyway, I don't think I *need* a higher end pic, these pics work fine
for what I need to do. I just need an accurate math library. If my 20
year old hp rpn calculator can accurately compute trig functions, I
have no doubt that my state-of-the-art PIC 16F can do it.
> Anyway, I don't think I *need* a higher end pic, these pics work fine
> for what I need to do. I just need an accurate math library. If my 20
> year old hp rpn calculator can accurately compute trig functions, I
> have no doubt that my state-of-the-art PIC 16F can do it.
I have little doubt that it can do it, but you wanted to know how you
can make it do it -- efficiently :)
So here's what I see as options (which definitely are not all possible
ones):
- Make sure you don't have an error in your experiment with the HiTech
doubles that returned the wrong value.
- Fix the HiTech library.
- Use the Microchip library (AFAIK they have a floating point lib in
assembly) and integrate that with your HiTech build (not easy, but not
impossible either).
- Write your own library.
The thing is that it's rather rare that someone uses floating point on a
16F. I'm using the HiTech compiler, and it works well for me, but I
haven't used floating point math at all on a PIC.
solarwind wrote:
> Does anyone know of a good C math library for 8 bit PICs (PIC16F
> type)? The ones HI-TECH C provides are a bit strange. The sine values
> that the sin function calculates are a bit off. My calculators and
> computers are all giving the right answer, but the HI-TECH library is
> only accurate to about three decimal places.
For what a PIC is usualy used for, that might very well
be enough. It's a precision vs. performance trade-off.
> After that, the numbers
> don't match my calculator and my computer. I looked at the source code
> for sine and it *looks* like they're using the CORDIC algorithm. I
> thought that (after reading various articles on the Internet) that
> most calculators use CORDIC to compute sine. So shouldn't my
> calculator and HI-TECH be giving the same answer? I'm building a
> calculator, so I want my math functions to be giving the right values.
>
> If anyone has any answers to explain this anomaly...
Probably design trade-offs. The libs probably has enought
precision for the common uses of a PIC processor. A "calculator"
is a very special case and I'd guess that you have to write
your own math functions the get the precision you need.
> or any links to
> other math libraries, I would really appreciate it.
>
> I tried to look through uClibc but their library is HUGE and designed
> for 32 bit architectures I believe. It would take wayyyyy too long to
> strip out the useful bits from their library. Same with other
> libraries I've looked at.
>
On Dec 30, 2008, at 2:43 AM, Jan-Erik Soderholm wrote:
>> but the HI-TECH library is
>> only accurate to about three decimal places.
>
> For what a PIC is usualy used for, that might very well
> be enough. It's a precision vs. performance trade-off.
That sounds about right. HI-TECH defaults to 24bit floats for both
"float" and "double", which is only 16 bits of mantissa, which sounds
like not much more than 3 digits. You can get 32bit doubles with the
"--double=32" switch, but that'll still be less precision than most
calculators.
> After that, the numbers
> don't match my calculator and my computer. I looked at the source code
> for sine and it *looks* like they're using the CORDIC algorithm. I
> thought that (after reading various articles on the Internet) that
> most calculators use CORDIC to compute sine. So shouldn't my
> calculator and HI-TECH be giving the same answer? I'm building a
> calculator, so I want my math functions to be giving the right values.
I thought most calculators used a series to calculate trig functions, as it
is about the only way to get sufficient accuracy to enough decimal places.
> On 2008-12-30 04:39:48, solarwind wrote:
>
> > On Tue, Dec 30, 2008 at 1:20 AM, Vitaliy <spamKILLspammaksimov.org> wrote:
> >> Use a higher end PIC. ;-)
>
> > Anyway, I don't think I *need* a higher end pic, these pics work fine
> > for what I need to do. I just need an accurate math library. If my 20
> > year old hp rpn calculator can accurately compute trig functions, I
> > have no doubt that my state-of-the-art PIC 16F can do it.
>
> I have little doubt that it can do it, but you wanted to know how you
> can make it do it -- efficiently :)
>
> So here's what I see as options (which definitely are not all possible
> ones):
>
> - Make sure you don't have an error in your experiment with the HiTech
> doubles that returned the wrong value.
> - Fix the HiTech library.
> - Use the Microchip library (AFAIK they have a floating point lib in
> assembly) and integrate that with your HiTech build (not easy, but not
> impossible either).
> - Write your own library.
>
> The thing is that it's rather rare that someone uses floating point on a
> 16F.
What transcendental functions do you need? How fast? This last question
is important in the choice between speed and size.
In application implementation consider the use of trig identities to
eliminate the need for libraries. (Define them with macros)
Scale the problem most trig functions operate between + - 1.0
use a signed int and treat it as fract.
Consider the use of a circle with 256 (or some other 2^^n) points
instead or radians (or degrees)
All of these can decrease the computational complexity. Some
of the most efficient trig implementations have been developed
by the computer gaming industry. (Google is your friend)
SIN/COS has often been implemented as a simple table with linear
interpretation. Scott Dattalo and others have regularly posted trig
functions for small PIC's.
Byte Craft implemented fixed point data types and used them for
a transcendental library. The computational complexity of float vs
fixed is very similar. Float gives larger dynamic range fixed increased
precision.
Our customers experience has been to effectively use trig functions
on the small and medium PIC's
Cordic on small processors with only single bit shifts may not
be as efficient as alternatives.
> I thought most calculators used a series to calculate trig functions, as it
> is about the only way to get sufficient accuracy to enough decimal places.
>
Apparently that is what the TI-8x calculators do. He doesn't have
enough code space to get the precision that a $2 calculator can offer.
> What transcendental functions do you need? How fast? This last
> question
> is important in the choice between speed and size.
He's implementing a calculator, so he needs "all" of the functions
implemented to at least 8 digits of precision, running at (probably)
somewhere faster than 2 calculations per second, but not as fast as 10
calculations per second.
I suspect that this is not the sort of performance point that most
microcontroller compiler libraries are going to be aiming at. He
might be better off writing his own floating point libraries from
scratch.
Does anyone know what sort of data formats most commercial calculators
use internally?
> On Dec 30, 2008, at 6:38 AM, Walter Banks wrote:
>
> > What transcendental functions do you need? How fast? This last
> > question
> > is important in the choice between speed and size.
>
> He's implementing a calculator, so he needs "all" of the functions
> implemented to at least 8 digits of precision, running at (probably)
> somewhere faster than 2 calculations per second, but not as fast as 10
> calculations per second.
>
> I suspect that this is not the sort of performance point that most
> microcontroller compiler libraries are going to be aiming at. He
> might be better off writing his own floating point libraries from
> scratch.
>
> Does anyone know what sort of data formats most commercial calculators
> use internally?
Up to the point where IEEE754 was formalized there was many
one of formats used.
As surprising number of current calculators are using IEEE 754
32 bit floats which have less precision than 8 digits. Of the half
dozen or so that I know details about that don't use IEEE754 they
use fixed point decimal, double and proprietary floating point
formats.
The transcendental implementation in the commercial calculators
I have seen generally has been implemented with taylor series or
something similar. Most use a single function and pass the series
constants or a pointer to a table of constants. Sometimes functions
are selected to take advantage of Horners method which reduces
the number of multiplies that are needed.
Calculators are often used as examples in compiler compiler parsers
and the generated code in these examples is generally C that compiles
into compact executables by most C compilers. There are two other
implementations that I know use either event driven parsers or
RPN often implemented in forth.