# Maths precision for Arduino?

I am looking at doing some geodetic calculations (Haversine formula) on GPS readings in my Arduino.

These calculations run out to greater than 8 decimal places and while I appreciate the speed of these calculations will be slow, the precision is important.

Will calculations done on a Due be more accurate than those done on an Uno, or is it more the compiler than the processor that is the determining factor?

Will including the math.h library improve precision?

Will calculations done on a Due be more accurate than those done on an Uno, or is it more the compiler than the processor that is the determining factor?

http://arduino.cc/en/Reference/Double

On the Arduino Due, doubles have 8-byte (64 bit) precision.

So, yes, calculations on the Due will be more accurate.

Will including the math.h library improve precision?

No. Nor will including the string.h library.

Due does support double, but none of the Arduinos have hardware floating point (until the Tre comes along I think), so throughput could be an issue unless you're only doing a few calculations at a time (not looping through a dataset). Expect performance to be 4 to 6 orders of magnitude down on a modern PC / graphics card.

I saw a little floating point coprocessor on Sparkfun the other day that wasn’t horribly expensive. I don’t know how useful it would be but it might be worth a look for projects that need maths beyond what the Arduino can handle.

You can get 19 places on an UNO using 64 bit integer math. Put the decimal place where you want by choosing smaller units. 1 meter = 1000000 micrometers = meters to 6 places.

But GPS is not even 1 meter accurate, is it? If you think so, take a reading, move 2 meters and take another. Even a Garmin with DGPS (Digital GPS) is only good to 3 to 5 meters. If it gives you numbers that look closer, it's up to you to know where to stop.

32 bit integer is good for 9 digits, 1 billion meters is over twice lunar distance.

If you will be multiplying like with scaling operations then be sure to work with smaller units to preserve accuracy.

This is not for people who don't understand maths but just punch calculator buttons and trust whatever they get. However this way with some care you can ensure that every digit is accurate and no IEEE FP trailing garbage.

You can get 19 places on an UNO using 64 bit integer math.

True, but the OP wants to use trigonometric and other advanced functions in his/her calculations.

DGPS (Digital GPS)

“Differential”, not “Digital”

Thanks guys,

...none of the Arduinos have hardware floating point..

Using doubles I can do "3.14159 * 6.587" in the Arduino so it would seem that one does not need hardware floating point to do floating point calculations. However I would expect the calcs to take longer. Then there's the question of how many decimal points the answer would be accurate to. Without hardware FP, at how many decimal places can I expect the rest to be rubbish?

Even a Garmin with DGPS (Digital GPS) is only good to 3 to 5 meters..

While the accuracy of standard GPS may be +/-5 meters the calculations are quite complex and taking into account the dimensions of the planet, 5 meters is quite miniscule. I also gave the wrong formula. I meant the more accurate Vincenty's algorithm which can get down to 0.5 mm accuracy on the face of the earth. Pretty fine tolerances.

Also I will hook the Arduino up to an RTK GPS which gives accuracy of ~1 inch.

for your application Chipkit uno is better. Since you can use double precision floating point liberary

lemming:
Using doubles I can do “3.14159 * 6.587” in the Arduino so it would seem that one does not need hardware floating point to do floating point calculations. However I would expect the calcs to take longer. Then there’s the question of how many decimal points the answer would be accurate to. Without hardware FP, at how many decimal places can I expect the rest to be rubbish?

The floating point software emulation uses the same IEEE formats that machines with hardware floating point use, so you don’t get any extra bits.

Here is a wiki page that describes IEEE 754. The Arduino and compatible processors that use the AVR chipsets (all of the official Arduinos except for the Due) use IEEE binary32 for both float and double. The processors that use ARM chips (Arduino Due, Teensy, DigiX, etc.) use IEEE binary32 for float, and IEEE binary64 for double: http://en.wikipedia.org/wiki/IEEE_floating_point

Using binary32, you get roughly 7 decimal digits, and a decimal exponent up to 37. Using binary64, you get roughly 15 decimal digits and a decimal exponent up to 306. Note, the numbers are calculated in binary, so the decimal digits and exponents is what you get looking at the binary number, and converting it to a decimal representation.

Using fixed-point integer math (or just choosing small units and printing the decimal point in later) I can do 19 places on an UNO in much the same way that I did math up through calculus before I ever had a hand calculator, on paper and chalk boards. All that can be done with floating point on an AVR Arduino can be done with integers faster and to greater accuracy if you put some mind to it.

If you think that you require FP to do trig then you haven't really thought enough. You don't.

Using pre-calculated tables, your app might run very, very fast indeed.

GoForSmoke: Using fixed-point integer math (or just choosing small units and printing the decimal point in later) I can do 19 places on an UNO in much the same way that I did math up through calculus before I ever had a hand calculator, on paper and chalk boards. All that can be done with floating point on an AVR Arduino can be done with integers faster and to greater accuracy if you put some mind to it.

If you think that you require FP to do trig then you haven't really thought enough. You don't.

Using pre-calculated tables, your app might run very, very fast indeed.

Precalculated tables for 19 place trig functions? That's more storage than Google own!

Yes you could rustle up some CORDIC routines, but its simpler and more hassle-free to use existing tried and tested FP libraries.

You wouldn't use 19 place trig values when dealing with 19 place variables. Can you guess why?

if my radius is 1234mm and the sine of 60 degrees to 3 places is 866 / 1000 I can accurately calculate 1234 * 866 / 1000 as long as I have enough places to hold the intermediate results.

I promise you that these techniques have been worked out and used extensively decades ago.

You don't have to table every possible angle. You only have to get close enough to interpolate with a required degree of precision that BTW, it's possible to beat what IEEE floating point can give you. If you need large tables then interface an SD card and maybe learn to use index files.

Generally when your code is doing the same set of calculations over and over you can precalculate chunks to all of that into one or more tables, early flight sims worked at all that way. Charles Moore the astronomer was aiming big telescopes to track objects using tables for fast fourier calcs before 1960 that way. It depends on what you're doing and your own ability to work out algorithms.

There are BCD techniques that allow math to arbitrarily high precisions, even beyond 100 places. They are completely accurate. Most hand calculators in the past used them and some or all still might.

Do what you want but realize that there's more than one viable way to skin a cat.

If you don't mind waiting for answers then sure. Finite series (like Taylor) can give you any desired precision, in time. In the old days when we chiseled stone tablets, that's how we made the tables we did use. I know table lookup from my days BC (before calculators) and I promise it works even to calculating orbits.

Consider that a trig table only needs sine and tangent for 1 quadrant. Cosine mirrors Sine.

How small of an angle do you need before simple interpolation will be within your tolerances? If you don't how how to even approach finding out then maybe you should see what reliance on machines and cookbook formulae has done to you, you can talk precision without knowing what and why or how and not be able to know if you got the right answer except that that's what popped up on a screen. That would make me shudder and feel insecure as to any results I got, but those who don't know better often feel just the opposite!

Even with floating point, table lookup is insanely faster than calculating even simple divides and multiplies. Arduinos tend to come with a good bit of flash that can be used for tables as well as code.

I am looking at doing some geodetic calculations (Haversine formula) on GPS readings in my Arduino.

Forget 32bit floating point.. For any such calculation is 64bit floating point the choice at minimum, or decimal arbitrary precision formats (slow but precise). Any other option is simply wasting your time.. The precision of 32bit fp used in arduino is maybe 6-7 decimal places for +-*/, but worse with transcendental functions..

This \$19 programmable GPS with FPU might also be an alternative consideration: http://bit.ly/1dBpits