From 545591727446bbc553b0cfb0cc9b6fefd2a16d9e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 28 Feb 2010 19:27:06 +0000 Subject: comparing Vector(-2, 0, 0) and Vector(2, 0, 0) was returning true, this bug is years old, strange nobody noticed. use float comparison from the "Ever Faster Float Comparisons" paper, tested with random values as well as random values converted to ints (where this existing code would fail). --- source/blender/python/generic/Mathutils.c | 35 +++++++++++++++---------------- source/blender/python/generic/vector.c | 7 +------ 2 files changed, 18 insertions(+), 24 deletions(-) (limited to 'source/blender/python') diff --git a/source/blender/python/generic/Mathutils.c b/source/blender/python/generic/Mathutils.c index 8ad388ac540..fc21c26dd74 100644 --- a/source/blender/python/generic/Mathutils.c +++ b/source/blender/python/generic/Mathutils.c @@ -557,25 +557,24 @@ static PyObject *M_Mathutils_ShearMatrix(PyObject * self, PyObject * args) /* Utility functions */ -/*---------------------- EXPP_FloatsAreEqual ------------------------- - Floating point comparisons - floatStep = number of representable floats allowable in between - float A and float B to be considered equal. */ -int EXPP_FloatsAreEqual(float A, float B, int floatSteps) -{ - int a, b, delta; - assert(floatSteps > 0 && floatSteps < (4 * 1024 * 1024)); - a = *(int*)&A; - if (a < 0) - a = 0x80000000 - a; - b = *(int*)&B; - if (b < 0) - b = 0x80000000 - b; - delta = abs(a - b); - if (delta <= floatSteps) - return 1; - return 0; +// LomontRRDCompare4, Ever Faster Float Comparisons by Randy Dillon +#define SIGNMASK(i) (-(int)(((unsigned int)(i))>>31)) + +int EXPP_FloatsAreEqual(float af, float bf, int maxDiff) +{ // solid, fast routine across all platforms + // with constant time behavior + int ai = *(int *)(&af); + int bi = *(int *)(&bf); + int test = SIGNMASK(ai^bi); + int diff, v1, v2; + + assert((0 == test) || (0xFFFFFFFF == test)); + diff = (ai ^ (test & 0x7fffffff)) - bi; + v1 = maxDiff + diff; + v2 = maxDiff - diff; + return (v1|v2) >= 0; } + /*---------------------- EXPP_VectorsAreEqual ------------------------- Builds on EXPP_FloatsAreEqual to test vectors */ int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps) diff --git a/source/blender/python/generic/vector.c b/source/blender/python/generic/vector.c index 1e44ddafd37..e320f87e9b9 100644 --- a/source/blender/python/generic/vector.c +++ b/source/blender/python/generic/vector.c @@ -1252,12 +1252,7 @@ static PyObject* Vector_richcmpr(PyObject *objectA, PyObject *objectB, int compa result = EXPP_VectorsAreEqual(vecA->vec, vecB->vec, vecA->size, 1); break; case Py_NE: - result = EXPP_VectorsAreEqual(vecA->vec, vecB->vec, vecA->size, 1); - if (result == 0){ - result = 1; - }else{ - result = 0; - } + result = !EXPP_VectorsAreEqual(vecA->vec, vecB->vec, vecA->size, 1); break; case Py_GT: lenA = vec_magnitude_nosqrt(vecA->vec, vecA->size); -- cgit v1.2.3