Index: src/pathops/SkPathOpsTypes.cpp |
diff --git a/src/pathops/SkPathOpsTypes.cpp b/src/pathops/SkPathOpsTypes.cpp |
index 999e1b215d1500279043e51756dd2d062185cef2..a076d155f2ffeda23e596d2c82188a6150b383bf 100644 |
--- a/src/pathops/SkPathOpsTypes.cpp |
+++ b/src/pathops/SkPathOpsTypes.cpp |
@@ -16,8 +16,7 @@ static bool equal_ulps(float A, float B, int epsilon) { |
floatIntA.fFloat = A; |
floatIntB.fFloat = B; |
// Different signs means they do not match. |
- if ((floatIntA.fSignBitInt < 0) != (floatIntB.fSignBitInt < 0)) |
- { |
+ if ((floatIntA.fSignBitInt < 0) != (floatIntB.fSignBitInt < 0)) { |
// Check for equality to make sure +0 == -0 |
return A == B; |
} |
@@ -26,6 +25,18 @@ static bool equal_ulps(float A, float B, int epsilon) { |
return ulpsDiff <= 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; |
+ } |
+ // Find the difference in ULPs. |
+ return floatIntA.fSignBitInt <= floatIntB.fSignBitInt + epsilon; |
+} |
+ |
bool AlmostEqualUlps(float A, float B) { |
const int UlpsEpsilon = 16; |
return equal_ulps(A, B, UlpsEpsilon); |
@@ -36,6 +47,12 @@ bool RoughlyEqualUlps(float A, float B) { |
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); |
+} |
+ |
// cube root approximation using bit hack for 64-bit float |
// adapted from Kahan's cbrt |
static double cbrt_5d(double d) { |