[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [27194] trunk/blender/source/blender/ python/generic: comparing Vector(-2, 0, 0) and Vector(2, 0, 0) was returning true, this bug is years old, strange nobody noticed.

Campbell Barton ideasman42 at gmail.com
Sun Feb 28 20:27:06 CET 2010


Revision: 27194
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=27194
Author:   campbellbarton
Date:     2010-02-28 20:27:06 +0100 (Sun, 28 Feb 2010)

Log Message:
-----------
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).

Modified Paths:
--------------
    trunk/blender/source/blender/python/generic/Mathutils.c
    trunk/blender/source/blender/python/generic/vector.c

Modified: trunk/blender/source/blender/python/generic/Mathutils.c
===================================================================
--- trunk/blender/source/blender/python/generic/Mathutils.c	2010-02-28 17:51:23 UTC (rev 27193)
+++ trunk/blender/source/blender/python/generic/Mathutils.c	2010-02-28 19:27:06 UTC (rev 27194)
@@ -557,25 +557,24 @@
 
 /* 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)

Modified: trunk/blender/source/blender/python/generic/vector.c
===================================================================
--- trunk/blender/source/blender/python/generic/vector.c	2010-02-28 17:51:23 UTC (rev 27193)
+++ trunk/blender/source/blender/python/generic/vector.c	2010-02-28 19:27:06 UTC (rev 27194)
@@ -1252,12 +1252,7 @@
 			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);





More information about the Bf-blender-cvs mailing list