I need (well, would like) to calculate an 8th-degree polynomial with coefficients on the order of 10^-23. I understand the Arduino can only handle precision to 6 or 7 decimal places. Is there a library out there to enhance the precision of these calculations, or should I just do this calculation in post-processing via Excel?
WizenedEE:
Well, since floating point numbers are essentially in scientific notation, if they're all small and don't need much precision, it would work.
5.427964E-23 is pretty high precision, I think. Even using a ChipKit UNO32 initializing all data points as long doubles, my polynomial solves to 0, when theory says it needs to solve to 5.16335556227116E-27.
Verdris:
5.427964E-23 is pretty high precision, I think. Even using a ChipKit UNO32 initializing all data points as long doubles, my polynomial solves to 0, when theory says it needs to solve to 5.16335556227116E-27.
My optical systems use 405nm laser radiation as the basis for particle detection and at that wavelength, Rayleigh scattering is a huge factor. The polynomial I use is part of the algorithm my team uses to calculate such scattering down to the order of less than 1 Mm^-1 so we can eliminate that from our readings. It works fine on our larger systems, but they're controlled by PCs running LabView. For the portable instruments we use the Arduinos.
Verdris:
5.427964E-23 is pretty high precision, I think. Even using a ChipKit UNO32 initializing all data points as long doubles, my polynomial solves to 0, when theory says it needs to solve to 5.16335556227116E-27.
5.427964E-23 is just as precise as 5427964.
Then do you have any suggestions on how to solve this:
Mixing types is not a good thing to do, when performing arithmetic operations.
f1 = 5791817 / (238.0185 - (1 / w2));
5791817 is an integer value, as is 1. Both will be interpreted as ints, which is OK for the 1, but not for 5791817.
You should be using 5791817.0 and 1.0.
It's also worth noting that 5791817.0 exceeds the number of digits that a float can accurately represent. Since the Arduino doesn't have a double type, you really are, I think, out of luck.
The link I gave above to the forum posting for arbitrary precision arithmetic should help. Whilst it won't be the fastest thing in the world, that's the trade-off you make: speed or precision. (Also high-precision numbers require quite a bit of progam memory).
It does not appear to support the higher functions like that. I experimented with the library a while back:
Calculations like e, pi, sine can be done in smallish loops. Given the sine(x) function you can calculate cosine(x), and given both sine and cosine you can get the tangent.
Then I found an algorithm for raising e to a power, and taking natural logs. So armed with all that, you could do most stuff.
Whether it is practical is another thing. The big number stuff tends to be slow, and a memory hog. Memory fragmentation would be an issue. Also using 12 Kb or so of your 32 kB of program memory may or may not be more than you can afford.
Still, it provides a workable alternative to simple floats, you can crank the precision up as much as you want. If you stick to modest levels of precision you can probably calculate sines, etc. quite quickly, and avoid too much fragmentation.