Approximately and Essentially Equal

I stumbled upon some old CS text the other day and was reminded of two functions approximatelyEqual(float, float, float) and essentiallyEqual(float, float, float). Since JavaScript uses a floating point system (IEEE) that is not exact, sometimes it returns numbers like 1.00000001 or 0.99999999, instead of 1. These functions can be used to allow floating point errors or when a margin of error is simply acceptable between two numbers.

How to do it…

The code for the two functions:

function approximatelyEqual(/* float */ a, /* float */ b, /* float */ epsilon) {
	var A = Math.abs(a), B = Math.abs(b);
	var Math.abs(A - B) <= (A < B ? B : A) * epsilon;
}

function essentiallyEqual(/* float */ a, /* float */ b, /* float */ epsilon) {
	var A = Math.abs(a), B = Math.abs(b);
	var Math.abs(A - B) <= (A > B ? B : A) * epsilon;
}

An simple example:

var a = 95.1, b = 100.0;
alert (approximatelyEqual(a, b, 0.05)); // this is true, 100 * 0.05 > 100 - 95.1
alert (essentiallyEqual(a, b, 0.05)); // this is false, 95.01 * 0.05 < 100 - 95.1 

How it works…

The arguments required for both functions are three numbers: the first and second arguments can be either the calculated value, or the target comparison value, and the third is the precision. The approximatelyEqual function uses the larger of the two values and multiples it by epsilon to determine the margin of error. The essentiallyEqual function uses the smaller of the two values and multiples it by epsilon to determine the margin of error. Therefore, unless values A and B are equal, the essentiallyEqual function will always require the values to be more precise than the approximatelyEqual function.

There’s more

Now that I understand git a lot better, I will be updating the Numbers package in the YUI 3 gallery with these two functions.