## Float precision

*Float precision* is a very subtle issue. It creeps up so rarely that many people (me included) would get it out of their heads completely before it would show itself somewhere once again.

Indeed, most of the time it's not a problem at all, that floating point computations are not ideally precise, and noone cares about the small additive noise that it produces, as long as you remember to avoid exact comparisons between floats.

Sometimes, however, the noise can severely spoil your day by violating the core assumptions, such as "*distance is always greater than zero*", or "*cosine of an angle never exceeds 1*".

The following is, I think, a marvellous example, discovered by Alex while debugging an obscure problem in one python program. I took the liberty of presenting it here using C++, however, the choice of the language is absolutely irrelevant. Try it in your favourite one, and you'll get the same result: the program will honestly report that the correlation distance between the points (6, 6) and (9, 9) is less than zero (which is something very unfortunate for a distance measure).

#include <iostream> using namespace std; double length(double a[]) { return sqrt(a[0]*a[0] + a[1]*a[1]); } double cosine_similarity(double a[], double b[]) { return (a[0]*b[0] + a[1]*b[1])/length(a)/length(b); } double cosine_distance(double a[], double b[]) { return 1 - cosine_similarity(a, b); } int main() { double a[2] = {6.0, 6.0}; double b[2] = {9.0, 9.0}; if (cosine_distance(a, b) >= 0) cout << "Yes" << endl; else cout << "No" << endl; return 0; }

So please, beware of float comparisons. In particular, think twice next time you implement your *sign()* function.