diff options
-rw-r--r-- | bench/MathBench.cpp | 7 | ||||
-rw-r--r-- | include/core/SkFloatingPoint.h | 9 | ||||
-rw-r--r-- | tests/ScalarTest.cpp | 24 |
3 files changed, 31 insertions, 9 deletions
diff --git a/bench/MathBench.cpp b/bench/MathBench.cpp index ffee901545..9feb5afb32 100644 --- a/bench/MathBench.cpp +++ b/bench/MathBench.cpp @@ -186,7 +186,7 @@ static bool isfinite_plus_int(const float data[4]) { } static bool isfinite_plus_float(const float data[4]) { - return !sk_float_isNaN(mulzeroadd(data)); + return !sk_float_isnan(mulzeroadd(data)); } static bool isfinite_plus_mulzero(const float data[4]) { @@ -212,11 +212,6 @@ static const struct { #undef MAKEREC -static bool SkScalarIsNaN_new(SkScalar x) { - float y = x * 0; - return y == y; -} - static bool isFinite(const SkRect& r) { // x * 0 will be NaN iff x is infinity or NaN. // a + b will be NaN iff either a or b is NaN. diff --git a/include/core/SkFloatingPoint.h b/include/core/SkFloatingPoint.h index b204e48595..ee91cd9799 100644 --- a/include/core/SkFloatingPoint.h +++ b/include/core/SkFloatingPoint.h @@ -67,10 +67,15 @@ static inline float sk_float_copysign(float x, float y) { #ifdef SK_BUILD_FOR_WIN #define sk_float_isfinite(x) _finite(x) - #define sk_float_isNaN(x) _isnan(x) + #define sk_float_isnan(x) _isnan(x) + static inline int sk_float_isinf(float x) { + int32_t bits = SkFloat2Bits(x); + return (bits << 1) == (0xFF << 24); + } #else #define sk_float_isfinite(x) isfinite(x) - #define sk_float_isNaN(x) isnan(x) + #define sk_float_isnan(x) isnan(x) + #define sk_float_isinf(x) isinf(x) #endif #ifdef SK_USE_FLOATBITS diff --git a/tests/ScalarTest.cpp b/tests/ScalarTest.cpp index 6c2df73199..2f0aa0bb5a 100644 --- a/tests/ScalarTest.cpp +++ b/tests/ScalarTest.cpp @@ -44,6 +44,20 @@ typedef bool (*IsFiniteProc2)(float, float, IsFiniteProc1); #endif +enum FloatClass { + kFinite, + kInfinite, + kNaN +}; + +static void test_floatclass(skiatest::Reporter* reporter, float value, FloatClass fc) { + // our sk_float_is... function may return int instead of bool, + // hence the double ! to turn it into a bool + REPORTER_ASSERT(reporter, !!sk_float_isfinite(value) == (fc == kFinite)); + REPORTER_ASSERT(reporter, !!sk_float_isinf(value) == (fc == kInfinite)); + REPORTER_ASSERT(reporter, !!sk_float_isnan(value) == (fc == kNaN)); +} + static void test_isfinite(skiatest::Reporter* reporter) { #ifdef SK_CAN_USE_FLOAT struct Rec { @@ -53,7 +67,15 @@ static void test_isfinite(skiatest::Reporter* reporter) { float max = 3.402823466e+38f; float inf = max * max; - float nan = 1 / sk_float_sin(0); + float nan = inf * 0; + + test_floatclass(reporter, 0, kFinite); + test_floatclass(reporter, max, kFinite); + test_floatclass(reporter, -max, kFinite); + test_floatclass(reporter, inf, kInfinite); + test_floatclass(reporter, -inf, kInfinite); + test_floatclass(reporter, nan, kNaN); + test_floatclass(reporter, -nan, kNaN); const Rec data[] = { { 0, true }, |