Go Down

Topic: Any ideas how to increase floating point accuracy? (Read 1 time) previous topic - next topic

David Pankhurst

Unfortunately, double is simply a synonym for float on the Arduino, and a quick look online showed no library for higher precision floating point (but it was a quick search - if anyone finds one, I too would like to know).

The float is a 32 bit variable, which ends up being about 6-7 digits of precison, and would explain the problem here:

http://www.arduino.cc/en/Reference/Float

For example, even your value of inc (0.1) won't store precisely, so you'll have problems.

One thought - convert these to longs:

Code: [Select]
long c0offset = -60;
long c1offset = 0;
long c2offset = 60;
long d01 = c1offset - c0offset;
long d02 = c2offset - c0offset;


Since they all seem to be integer anyways, and then change the formula:

Code: [Select]
x01 = ((sq(d01) - sq(Rcircle1) + sq(Rcircle0)) / (2.0 * d01)) + c0offset;
to
Code: [Select]
long temp1=2*d01;
long temp2=d01*d01;
x01 = ((temp2 - sq(Rcircle1) + sq(Rcircle0)) / temp ) + c0offset;


It won't do much, but you'll save two floating point multiplies, and resultant loss of precision.

MarkT

Sorry people to disagree: 7 digits is more than plenty for these calculations - this is simple trigonometry. 

My suspicion is a bug in the program, use of int where float was intended, different rounding/truncation - or it might be a bug in Arduino float library, but that's less likely I feel.

Another possibility is use of a badly conditioned numerical technique that is multiplying up errors, often a gotcha for naive application of equations without error-analysis.

If the complete code was available someone could reproduce the problem and work out what's going wrong.
[ I won't respond to messages, use the forum please ]

Spine

Ok, It turns out I am an idiot!

I had a slight error in my Y position calculation, + instead of -  (comes from c^2 - a^2 = b^2).  I was so involved with thinking of all these other possibilities I overlooked a simple pythagorean theorem typo.

I re-ran my simulations with comparing to microsoft excel and the arduino answers are on average about 0.5mm off either direction with the worst case around 1mm error.  This is well within the error of other parameters in my system so It is good enough for this application.

Thanks to all that answered and sorry for my massive loss of brain function!   :D

MarkT

Its always good to do a back-of-the-envelop sanity calculation to check the result is in the right ballpark - unless you were triangulating on the scale of GPS I knew single floats are accurate enough... 

If you frame a posting along the lines of "this is what I expect to see", "but this is what I am seeing",  then someone can have a go and working out which is actually wrong...  If you just say "blah is broken" we don't have a handle on things.
[ I won't respond to messages, use the forum please ]

robtillaart


you are using floats to represent the mm.

Code: [Select]
  float inc = 0.1;  // set to 0.1cm or 1mm

You could also do most/all of the math in mm. You will get

Code: [Select]
  int inc = 1; // set to 1 mm
  unsigned long Rcircle0 = 0;   // a radius cannot be negative afaik
  etc



Using long instead of float would improve the accuracy, speed up the math and decrease the footprint of the sketch. There might be a few places were floats are needed but give it a try.



Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Go Up