#include <string>
#include <stdio.h>
#include <cmath>
#include <assert.h>
#include <vector>
#include <stdlib.h>
#define USE_DOT
//#define USE_SSE
static const float CMP_EPS = 0.01f;
static const float CMP_EPS2 = 0.01f * 0.01f * 1.539f;
typedef float v4sf __attribute__ ((vector_size (16))); // vector of three single floats
struct f3vector {
union
{
v4sf v;
struct { float x,y,z,w; };
struct { int ix,iy,iz,iw; };
};
};
struct float3 : public f3vector {
float3(const float _x, const float _y, const float _z) {
x = _x; y = _y; z = _z;
}
#ifdef USE_SSE
float3& operator+= (const float3& f) {
v += f.v;
return *this;
}
float3& operator-= (const float3& f) {
v -= f.v;
return *this;
}
#else
float3& operator+= (const float3& f) {
x += f.x; y += f.y; z += f.z;
return *this;
}
float3& operator-= (const float3& f) {
x -= f.x; y -= f.y; z -= f.z;
return *this;
}
#endif
inline float SqDistance(const float3& f) const {
const float dx = x - f.x;
const float dy = y - f.y;
const float dz = z - f.z;
return (dx*dx + dy*dy + dz*dz);
}
#ifdef USE_DOT
bool equals(const float3& f) const {
return this->SqDistance(f) <= (CMP_EPS2);
}
#elif defined(USE_SSE)
bool equals(float3& f) {
f3vector n;
n.v = (v - f.v);
n.v *= n.v;
return (n.x + n.y + n.z) <= (CMP_EPS2);
}
#else
bool equals(const float3& f) const {
return std::fabs(x - f.x) <= CMP_EPS
&& std::fabs(y - f.y) <= CMP_EPS
&& std::fabs(z - f.z) <= CMP_EPS;
}
#endif
};
int main() {
int x = 0;
float3 a(0.1f,0.1f,0.1f);
float3 b((float)rand()/(float)RAND_MAX, (float)rand()/(float)RAND_MAX, (float)rand()/(float)RAND_MAX);
for (int i = 1<<25; i>0; --i) {
if (a.equals(b)) {
x++;
}
a.x = (i%3 == 0) ? (float)rand()/(float)RAND_MAX : a.x;
a.y = (i%3 == 1) ? (float)rand()/(float)RAND_MAX : a.y;
a.z = (i%3 == 2) ? (float)rand()/(float)RAND_MAX : a.z;
}
printf("%i\n", x);
return 0;
}