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 <reed@google.com> Commit-Queue: Mike Reed <reed@google.com>
This commit is contained in:
parent
b86aaeb7b0
commit
8addae8b53
@ -11,6 +11,7 @@
|
||||
|
||||
#include "SkTypes.h"
|
||||
#include "SkSafe_math.h"
|
||||
#include <float.h>
|
||||
|
||||
/** 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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user