I was doing some background animation recently, which led me into the realm of real numbers, well-known as the bane of programming everywhere.
For the uninitiated (sad to say there are "programmers" that probably know nothing about IEEE number formats), it sucks because only very few numbers can be represented exactly, and this leads us directly into the world of accumulated error and uncertainty.
Big fucking deal! Spare me your gobbledygook! Just let me treat them like integers, and leave me alone...
Take this innocent loop for a quick example. Really. Take it, and paste into your IDE, and run it.
float total = 0.0f;
float incr = 0.005f;
while(true) {
Console.WriteLine(total);
total += incr;
}
Now, you desparately want the output of this loop to be [.005,.010,.015,.020,...] but you are going to be disappointed when you run it.
Dude, you are scaring me now....
How can this be? Pretty simple actually. Powers of ten and powers of two don't like each other very much; go back and read the first two paragraphs up there.
In the meantime, all is not lost. A more precise way to do the same thing is the following:
int ix = 0;
float total = 0.0f;
float incr = 0.005f;
while(true) {
Console.WriteLine(total);
total = (float)ix*incr;
ix++;
}
What makes this code more accurate (i.e. better) is the distinct lack of accumulated error. The (floating-point) number for the current iteration is the result of O(1) calculations, where as the other loop's is O(n) calculations.
Of course, this also means that directly testing for equality of two floating-point numbers is also a sticky wicket. Let's just save that for another time....
No comments:
Post a Comment