Equal
From Odwiki
The VEX comparison operator "==", tests for absolute equality between the left- and right-hand sides. But floating point values are encoded in binary form, and this means that some decimal values can not be represented exactly. As a result, you may find that two values that you would expect to compare equal, don't -- especially if one of them was involved in a different set of operations than the other.
Typically, the values end up being different by only a very small amount -- so small in fact, that they should compare as equals for our purposes, but fail the normal test because they are not absolutely identical. In mathematics, it is customary to denote a very small amount with the greek letter epsilon.
These functions then, compare two values and declare them "equal" if their absolute difference falls within this tiny amount. How big this amount should be depends on the context of the operations, but it is usually related to the types of values being compared; and since it is only meaningful for floating point types, and since there's only one floating point type in VEX, we can probably agree that something around 1e-5 is probably a safe choice for the majority of cases. There are times however, when you want to have direct control over this value, so it's a good idea to cover both cases.
The function names are a little unsightly but, until we can overload function names in VEX, we're stuck with the yucky names, sorry :(
For the technically inclined: The type of comparison used here is usually referred to as a "weak" comparison -> (|a-b|<=EPSILON*|a| || |a-b|<=EPSILON*|b|). There's also a so-called "strong" comparison which is a little stricter -> (|a-b|<=EPSILON*|a| && |a-b|<=EPSILON*|b|), but I decided to just do the weak one here.
Here is a VEX implementation of equal incorporating an epsilon.
#define EPSILON 1e-5 // Equality Comparison With Built-in Epsilon //--------------------------------------------------------------------- // Float int equal(float a,{ float d=abs(a-
; if(d<=(EPSILON*abs(a)) || d<=(EPSILON*abs(
)) return 1; return 0; } // Vector int equalV(vector a,
{ return (equal(a.x,b.x) && equal(a.y,b.y) && equal(a.z,b.z)); } // Vector4 int equalV4(vector4 a,
{ return (equal(a.x,b.x) && equal(a.y,b.y) && equal(a.z,b.z) && equal(a.w,b.w) ); } // Equality Comparison With User-Supplied Epsilon //--------------------------------------------------------------------- // Float int equalEps(float a,b, e) { float d=abs(a-
; if(d<=(e*abs(a)) || d<=(e*abs(
)) return 1; return 0; } // Vector int equalEpsV(vector a,b; float e) { return (equalEps(a.x,b.x,e) && equalEps(a.y,b.y,e) && equalEps(a.z,b.z,e)); } // Vector4 int equalEpsV4(vector4 a,b; float e) { return (equalEps(a.x,b.x,e) && equalEps(a.y,b.y,e) && equalEps(a.z,b.z,e) && equalEps(a.w,b.w,e) );



