Hacker News new | past | comments | ask | show | jobs | submit login

That's why you don't compare floating point numbers with the = operator.

You use something like:

    fabs( a-b ) < epsilon
where epsilon is usually defined by the language as a very small quantity (example values in C are 1E-8 for a float, 1E-15 for double), or you can just use a hard coded value appropriate to the values you are comparing.



That "where epsilon is usually defined by the language as a very small quantity" is BAD advice. double.epsilon and float.epsilon (std::numeric_limits::epsilon in C++) are "machine epsilons": numbers equal to the difference between 1 and the next representable value. In other words: 1 and 1+epsilon can be represented exactly, but there are no representable numbers between the two. The distance between representable numbers never goes down when you move away from zero. That means, that, for x,y >= 1 there is no difference between

       x == y

and

     |x - y| < epsilon

As I said, things get worse if your comparison is between larger numbers. For example, the smallest double larger than 1024 is 1024+1024 epsilon (IIRC; I am too lazy to double-check that now)

The epsilon used in numerical algorithms is an entirely different beast than the machine epsilon.

That epsilon you should pick as follows: make a numerical analysis of your problem, choose a good algorithm, and determine the desired accuracy of your answer. From those, derive a (relative, absolute, whatever) error you can live with.

Alternatively, pick a reasonable value from thin air and hope for the best/test your code to get confidence that it will return good values (do not do this when programming flight control software, pacemakers, etc). Oftentimes, it is not really hard to produce a reasonable value. For example, an iterative procedure that produces pixel coordinate likely can stop once the absolute error is less than .01 pixel, and possibly a lot earlier.

Finally, in the ideal world, you will use a good way to test for your accuracy, for example one from boost test: http://www.boost.org/doc/libs/1_52_0/libs/test/doc/html/utf/... (contains useful links to more in-depth discussions)

And, by the way, 1E-8 is lower than the machine epsilon for floats, and 1E-15 larger than that for doubles. http://en.wikipedia.org/wiki/Machine_epsilon gives them as 1.2E-7, respectively 2.2E-16.


Thanks for the clarification, I did say they were examples (they were the first results I found in a quick google) and that you should use epsilon values appropriate to the values you are comparing.


yes, we're currently doing that. look here: https://github.com/sjkaliski/numbers.js/blob/master/lib/numb...




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: