| OLD | NEW | 
|   1 /* |   1 /* | 
|   2  * Copyright 2012 Google Inc. |   2  * Copyright 2012 Google Inc. | 
|   3  * |   3  * | 
|   4  * Use of this source code is governed by a BSD-style license that can be |   4  * Use of this source code is governed by a BSD-style license that can be | 
|   5  * found in the LICENSE file. |   5  * found in the LICENSE file. | 
|   6  */ |   6  */ | 
|   7 #include "SkFloatBits.h" |   7 #include "SkFloatBits.h" | 
|   8 #include "SkPathOpsTypes.h" |   8 #include "SkPathOpsTypes.h" | 
|   9  |   9  | 
|  10  |  10  | 
|  11  |  11  | 
|  12 // from http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-num
    bers-2012-edition/ |  12 // from http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-num
    bers-2012-edition/ | 
|  13 // FIXME: move to SkFloatBits.h |  13 // FIXME: move to SkFloatBits.h | 
|  14 static bool equal_ulps(float A, float B, int epsilon) { |  14 static bool equal_ulps(float A, float B, int epsilon) { | 
|  15     SkFloatIntUnion floatIntA, floatIntB; |  15     SkFloatIntUnion floatIntA, floatIntB; | 
|  16     floatIntA.fFloat = A; |  16     floatIntA.fFloat = A; | 
|  17     floatIntB.fFloat = B; |  17     floatIntB.fFloat = B; | 
|  18     // Different signs means they do not match. |  18     // Different signs means they do not match. | 
|  19     if ((floatIntA.fSignBitInt < 0) != (floatIntB.fSignBitInt < 0)) |  19     if ((floatIntA.fSignBitInt < 0) != (floatIntB.fSignBitInt < 0)) { | 
|  20     { |  | 
|  21         // Check for equality to make sure +0 == -0 |  20         // Check for equality to make sure +0 == -0 | 
|  22         return A == B; |  21         return A == B; | 
|  23     } |  22     } | 
|  24     // Find the difference in ULPs. |  23     // Find the difference in ULPs. | 
|  25     int ulpsDiff = abs(floatIntA.fSignBitInt - floatIntB.fSignBitInt); |  24     int ulpsDiff = abs(floatIntA.fSignBitInt - floatIntB.fSignBitInt); | 
|  26     return ulpsDiff <= epsilon; |  25     return ulpsDiff <= epsilon; | 
|  27 } |  26 } | 
|  28  |  27  | 
 |  28 static bool less_ulps(float A, float B, int epsilon) { | 
 |  29     SkFloatIntUnion floatIntA, floatIntB; | 
 |  30     floatIntA.fFloat = A; | 
 |  31     floatIntB.fFloat = B; | 
 |  32     // Check different signs with float epsilon since we only care if they're bo
    th close to 0. | 
 |  33     if ((floatIntA.fSignBitInt < 0) != (floatIntB.fSignBitInt < 0)) { | 
 |  34         return A <= B + FLT_EPSILON * epsilon; | 
 |  35     } | 
 |  36     // Find the difference in ULPs. | 
 |  37     return floatIntA.fSignBitInt <= floatIntB.fSignBitInt + epsilon; | 
 |  38 } | 
 |  39  | 
|  29 bool AlmostEqualUlps(float A, float B) { |  40 bool AlmostEqualUlps(float A, float B) { | 
|  30     const int UlpsEpsilon = 16; |  41     const int UlpsEpsilon = 16; | 
|  31     return equal_ulps(A, B, UlpsEpsilon); |  42     return equal_ulps(A, B, UlpsEpsilon); | 
|  32 } |  43 } | 
|  33  |  44  | 
|  34 bool RoughlyEqualUlps(float A, float B) { |  45 bool RoughlyEqualUlps(float A, float B) { | 
|  35     const int UlpsEpsilon = 256; |  46     const int UlpsEpsilon = 256; | 
|  36     return equal_ulps(A, B, UlpsEpsilon); |  47     return equal_ulps(A, B, UlpsEpsilon); | 
|  37 } |  48 } | 
|  38  |  49  | 
 |  50 bool AlmostBetweenUlps(float a, float b, float c) { | 
 |  51     const int UlpsEpsilon = 1; | 
 |  52     return a <= c ? less_ulps(a, b, UlpsEpsilon) && less_ulps(b, c, UlpsEpsilon) | 
 |  53         : less_ulps(b, a, UlpsEpsilon) && less_ulps(c, b, UlpsEpsilon); | 
 |  54 } | 
 |  55  | 
|  39 // cube root approximation using bit hack for 64-bit float |  56 // cube root approximation using bit hack for 64-bit float | 
|  40 // adapted from Kahan's cbrt |  57 // adapted from Kahan's cbrt | 
|  41 static double cbrt_5d(double d) { |  58 static double cbrt_5d(double d) { | 
|  42     const unsigned int B1 = 715094163; |  59     const unsigned int B1 = 715094163; | 
|  43     double t = 0.0; |  60     double t = 0.0; | 
|  44     unsigned int* pt = (unsigned int*) &t; |  61     unsigned int* pt = (unsigned int*) &t; | 
|  45     unsigned int* px = (unsigned int*) &d; |  62     unsigned int* px = (unsigned int*) &d; | 
|  46     pt[1] = px[1] / 3 + B1; |  63     pt[1] = px[1] / 3 + B1; | 
|  47     return t; |  64     return t; | 
|  48 } |  65 } | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
|  65 double SkDCubeRoot(double x) { |  82 double SkDCubeRoot(double x) { | 
|  66     if (approximately_zero_cubed(x)) { |  83     if (approximately_zero_cubed(x)) { | 
|  67         return 0; |  84         return 0; | 
|  68     } |  85     } | 
|  69     double result = halley_cbrt3d(fabs(x)); |  86     double result = halley_cbrt3d(fabs(x)); | 
|  70     if (x < 0) { |  87     if (x < 0) { | 
|  71         result = -result; |  88         result = -result; | 
|  72     } |  89     } | 
|  73     return result; |  90     return result; | 
|  74 } |  91 } | 
| OLD | NEW |