Index: src/pathops/SkPathOpsTypes.cpp |
diff --git a/src/pathops/SkPathOpsTypes.cpp b/src/pathops/SkPathOpsTypes.cpp |
index 8135c57025757fa0b2f2d815a052b39e53b5e7e5..2d7388b8822329f48ac91d512082f476835b2901 100644 |
--- a/src/pathops/SkPathOpsTypes.cpp |
+++ b/src/pathops/SkPathOpsTypes.cpp |
@@ -7,34 +7,52 @@ |
#include "SkFloatBits.h" |
#include "SkPathOpsTypes.h" |
- |
- |
// from http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ |
// FIXME: move to SkFloatBits.h |
static bool equal_ulps(float a, float b, int epsilon) { |
- SkFloatIntUnion floatIntA, floatIntB; |
- floatIntA.fFloat = a; |
- floatIntB.fFloat = b; |
- // Different signs means they do not match. |
- if ((floatIntA.fSignBitInt < 0) != (floatIntB.fSignBitInt < 0)) { |
- // Check for equality to make sure +0 == -0 |
- return a == b; |
+ if (!SkScalarIsFinite(a) || !SkScalarIsFinite(b)) { |
+ return false; |
} |
+ int aBits = SkFloatAs2sCompliment(a); |
+ int bBits = SkFloatAs2sCompliment(b); |
// Find the difference in ULPs. |
- int ulpsDiff = abs(floatIntA.fSignBitInt - floatIntB.fSignBitInt); |
- return ulpsDiff <= epsilon; |
+ return aBits < bBits + epsilon && bBits < aBits + epsilon; |
+} |
+ |
+static bool not_equal_ulps(float a, float b, int epsilon) { |
+ if (!SkScalarIsFinite(a) || !SkScalarIsFinite(b)) { |
+ return false; |
+ } |
+ int aBits = SkFloatAs2sCompliment(a); |
+ int bBits = SkFloatAs2sCompliment(b); |
+ // Find the difference in ULPs. |
+ return aBits >= bBits + epsilon || bBits >= aBits + epsilon; |
} |
static bool less_ulps(float a, float b, int epsilon) { |
- SkFloatIntUnion floatIntA, floatIntB; |
- floatIntA.fFloat = a; |
- floatIntB.fFloat = b; |
- // Check different signs with float epsilon since we only care if they're both close to 0. |
- if ((floatIntA.fSignBitInt < 0) != (floatIntB.fSignBitInt < 0)) { |
- return a <= b + FLT_EPSILON * epsilon; |
+ if (!SkScalarIsFinite(a) || !SkScalarIsFinite(b)) { |
+ return false; |
} |
+ int aBits = SkFloatAs2sCompliment(a); |
+ int bBits = SkFloatAs2sCompliment(b); |
// Find the difference in ULPs. |
- return floatIntA.fSignBitInt <= floatIntB.fSignBitInt + epsilon; |
+ return aBits <= bBits - epsilon; |
+} |
+ |
+static bool less_or_equal_ulps(float a, float b, int epsilon) { |
+ if (!SkScalarIsFinite(a) || !SkScalarIsFinite(b)) { |
+ return false; |
+ } |
+ int aBits = SkFloatAs2sCompliment(a); |
+ int bBits = SkFloatAs2sCompliment(b); |
+ // Find the difference in ULPs. |
+ return aBits < bBits + epsilon; |
+} |
+ |
+// equality using the same error term as between |
+bool AlmostBequalUlps(float a, float b) { |
+ const int UlpsEpsilon = 2; |
+ return equal_ulps(a, b, UlpsEpsilon); |
} |
bool AlmostEqualUlps(float a, float b) { |
@@ -42,18 +60,36 @@ bool AlmostEqualUlps(float a, float b) { |
return equal_ulps(a, b, UlpsEpsilon); |
} |
+bool NotAlmostEqualUlps(float a, float b) { |
+ const int UlpsEpsilon = 16; |
+ return not_equal_ulps(a, b, UlpsEpsilon); |
+} |
+ |
bool RoughlyEqualUlps(float a, float b) { |
const int UlpsEpsilon = 256; |
return equal_ulps(a, b, UlpsEpsilon); |
} |
bool AlmostBetweenUlps(float a, float b, float c) { |
- const int UlpsEpsilon = 1; |
- return a <= c ? less_ulps(a, b, UlpsEpsilon) && less_ulps(b, c, UlpsEpsilon) |
- : less_ulps(b, a, UlpsEpsilon) && less_ulps(c, b, UlpsEpsilon); |
+ const int UlpsEpsilon = 2; |
+ return a <= c ? less_or_equal_ulps(a, b, UlpsEpsilon) && less_or_equal_ulps(b, c, UlpsEpsilon) |
+ : less_or_equal_ulps(b, a, UlpsEpsilon) && less_or_equal_ulps(c, b, UlpsEpsilon); |
+} |
+ |
+bool AlmostLessUlps(float a, float b) { |
+ const int UlpsEpsilon = 16; |
+ return less_ulps(a, b, UlpsEpsilon); |
+} |
+ |
+bool AlmostLessOrEqualUlps(float a, float b) { |
+ const int UlpsEpsilon = 16; |
+ return less_or_equal_ulps(a, b, UlpsEpsilon); |
} |
int UlpsDistance(float a, float b) { |
+ if (!SkScalarIsFinite(a) || !SkScalarIsFinite(b)) { |
+ return SK_MaxS32; |
+ } |
SkFloatIntUnion floatIntA, floatIntB; |
floatIntA.fFloat = a; |
floatIntB.fFloat = b; |