From 8addae8b539a2db6ed34d34bf12609fbc0b2d198 Mon Sep 17 00:00:00 2001 From: Mike Reed Date: Fri, 4 Aug 2017 15:12:14 -0400 Subject: [PATCH] just use math.h for converting from float to int Bug: skia: Change-Id: I40cce503cd4cef09c671511a705192efc5d67d71 Reviewed-on: https://skia-review.googlesource.com/31002 Reviewed-by: Mike Reed Commit-Queue: Mike Reed --- include/private/SkFloatBits.h | 13 ++++++ tests/MathTest.cpp | 86 ----------------------------------- 2 files changed, 13 insertions(+), 86 deletions(-) diff --git a/include/private/SkFloatBits.h b/include/private/SkFloatBits.h index 4909926f13..7a4c708218 100644 --- a/include/private/SkFloatBits.h +++ b/include/private/SkFloatBits.h @@ -11,6 +11,7 @@ #include "SkTypes.h" #include "SkSafe_math.h" +#include /** Convert a sign-bit int (i.e. float interpreted as int) into a 2s compliement int. This also converts -0 (0x80000000) to 0. Doing this to a float allows @@ -79,21 +80,33 @@ static inline int32_t pin_double_to_int(double x) { If the value is out of range, or NaN, return +/- SK_MaxS32 */ static inline int32_t SkFloatToIntFloor(float x) { +#ifdef SK_SUPPORT_LEGACY_FLOATBITS return pin_double_to_int(floor(x)); +#else + return (int)floorf(x); +#endif } /** Return the float rounded to an int. If the value is out of range, or NaN, return +/- SK_MaxS32 */ static inline int32_t SkFloatToIntRound(float x) { +#ifdef SK_SUPPORT_LEGACY_FLOATBITS return pin_double_to_int(floor((double)x + 0.5)); +#else + return (int)floorf(x + 0.5f); +#endif } /** Return the ceiling of the float as an int. If the value is out of range, or NaN, return +/- SK_MaxS32 */ static inline int32_t SkFloatToIntCeil(float x) { +#ifdef SK_SUPPORT_LEGACY_FLOATBITS return pin_double_to_int(ceil(x)); +#else + return (int)ceilf(x); +#endif } // Scalar wrappers for float-bit routines diff --git a/tests/MathTest.cpp b/tests/MathTest.cpp index 0bd3cf5da5..3d30f0db2a 100644 --- a/tests/MathTest.cpp +++ b/tests/MathTest.cpp @@ -5,14 +5,10 @@ * found in the LICENSE file. */ -#include "float.h" - #include "SkColorPriv.h" #include "SkEndian.h" #include "SkFDot6.h" #include "SkFixed.h" -#include "SkFloatBits.h" -#include "SkFloatingPoint.h" #include "SkHalf.h" #include "SkMathPriv.h" #include "SkPoint.h" @@ -233,87 +229,6 @@ static void check_length(skiatest::Reporter* reporter, REPORTER_ASSERT(reporter, len > 0.999f && len < 1.001f); } -static float nextFloat(SkRandom& rand) { - SkFloatIntUnion data; - data.fSignBitInt = rand.nextU(); - return data.fFloat; -} - -/* returns true if a == b as resulting from (int)x. Since it is undefined - what to do if the float exceeds 2^32-1, we check for that explicitly. - */ -static bool equal_float_native_skia(float x, int32_t ni, int32_t si) { - // When the float is out of integer range (NaN, above, below), - // the C cast is undefined, but Skia's methods should have clamped. - if (!(x == x)) { // NaN - return si == SK_MaxS32 || si == SK_MinS32; - } - if (x > SK_MaxS32) { - return si == SK_MaxS32; - } - if (x < SK_MinS32) { - return si == SK_MinS32; - } - return si == ni; -} - -static void assert_float_equal(skiatest::Reporter* reporter, const char op[], - float x, int32_t ni, int32_t si) { - if (!equal_float_native_skia(x, ni, si)) { - ERRORF(reporter, "%s float %g bits %x native %x skia %x\n", - op, x, SkFloat2Bits(x), ni, si); - } -} - -static void test_float_floor(skiatest::Reporter* reporter, float x) { - int ix = (int)floor(x); - int iix = SkFloatToIntFloor(x); - assert_float_equal(reporter, "floor", x, ix, iix); -} - -static void test_float_round(skiatest::Reporter* reporter, float x) { - double xx = x + 0.5; // need intermediate double to avoid temp loss - int ix = (int)floor(xx); - int iix = SkFloatToIntRound(x); - assert_float_equal(reporter, "round", x, ix, iix); -} - -static void test_float_ceil(skiatest::Reporter* reporter, float x) { - int ix = (int)ceil(x); - int iix = SkFloatToIntCeil(x); - assert_float_equal(reporter, "ceil", x, ix, iix); -} - -static void test_float_conversions(skiatest::Reporter* reporter, float x) { - test_float_floor(reporter, x); - test_float_round(reporter, x); - test_float_ceil(reporter, x); -} - -static void unittest_fastfloat(skiatest::Reporter* reporter) { - SkRandom rand; - size_t i; - - static const float gFloats[] = { - 0.f/0.f, -0.f/0.f, 1.f/0.f, -1.f/0.f, - 0.f, 1.f, 0.5f, 0.499999f, 0.5000001f, 1.f/3, - 0.000000001f, 1000000000.f, // doesn't overflow - 0.0000000001f, 10000000000.f // does overflow - }; - for (i = 0; i < SK_ARRAY_COUNT(gFloats); i++) { - test_float_conversions(reporter, gFloats[i]); - test_float_conversions(reporter, -gFloats[i]); - } - - for (int outer = 0; outer < 100; outer++) { - rand.setSeed(outer); - for (i = 0; i < 100000; i++) { - float x = nextFloat(rand); - test_float_conversions(reporter, x); - } - } -} - static float make_zero() { return sk_float_sin(0); } @@ -573,7 +488,6 @@ DEF_TEST(Math, reporter) { REPORTER_ASSERT(reporter, (SkFixedCeilToFixed(-SK_Fixed1 * 10) >> 1) == -SK_Fixed1 * 5); } - unittest_fastfloat(reporter); unittest_isfinite(reporter); unittest_half(reporter); test_rsqrt(reporter, sk_float_rsqrt);