diff options
author | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2011-12-05 20:49:37 +0000 |
---|---|---|
committer | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2011-12-05 20:49:37 +0000 |
commit | d230e3e532dbb0df39453375f9918608d1e71b54 (patch) | |
tree | 56325c0e6e91852c27fcd77e72403d45ff4e7a5b /tests/ScalarTest.cpp | |
parent | 5192b4e3c60717c70e9ece4f48c5da80387a981e (diff) |
add test for isFinite
git-svn-id: http://skia.googlecode.com/svn/trunk@2800 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'tests/ScalarTest.cpp')
-rw-r--r-- | tests/ScalarTest.cpp | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/tests/ScalarTest.cpp b/tests/ScalarTest.cpp new file mode 100644 index 0000000000..2848516b97 --- /dev/null +++ b/tests/ScalarTest.cpp @@ -0,0 +1,115 @@ +/* + * Copyright 2011 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "Test.h" +#include "SkFloatingPoint.h" +#include "SkMath.h" +#include "SkPoint.h" +#include "SkRandom.h" + +#ifdef SK_CAN_USE_FLOAT + +static bool isFinite_int(float x) { + uint32_t bits = SkFloat2Bits(x); // need unsigned for our shifts + int exponent = bits << 1 >> 24; + return exponent != 0xFF; +} + +static bool isFinite_float(float x) { + return isfinite(x); +} + +static bool isFinite_mulzero(float x) { + float y = x * 0; + return y == y; +} + +// return true if the float is finite +typedef bool (*IsFiniteProc1)(float); + +static bool isFinite2_and(float x, float y, IsFiniteProc1 proc) { + return proc(x) && proc(y); +} + +static bool isFinite2_mulzeroadd(float x, float y, IsFiniteProc1 proc) { + return proc(x * 0 + y * 0); +} + +// return true if both floats are finite +typedef bool (*IsFiniteProc2)(float, float, IsFiniteProc1); + +#endif + +static void test_isfinite(skiatest::Reporter* reporter) { +#ifdef SK_CAN_USE_FLOAT + struct Rec { + float fValue; + bool fIsFinite; + }; + + float max = 3.402823466e+38f; + float inf = max * max; + float nan = 1 / sk_float_sin(0); + + const Rec data[] = { + { 0, true }, + { 1, true }, + { -1, true }, + { max * 0.75, true }, + { max, true }, + { -max * 0.75, true }, + { -max, true }, + { inf, false }, + { -inf, false }, + { nan, false }, + }; + + const IsFiniteProc1 gProc1[] = { + isFinite_int, + isFinite_float, + isFinite_mulzero + }; + const IsFiniteProc2 gProc2[] = { + isFinite2_and, + isFinite2_mulzeroadd + }; + + int i, n = SK_ARRAY_COUNT(data); + + for (i = 0; i < n; ++i) { + for (int k = 0; k < SK_ARRAY_COUNT(gProc1); ++k) { + const Rec& rec = data[i]; + bool finite = gProc1[k](rec.fValue); + REPORTER_ASSERT(reporter, rec.fIsFinite == finite); + } + } + + for (i = 0; i < n; ++i) { + const Rec& rec0 = data[i]; + for (int j = 0; j < n; ++j) { + const Rec& rec1 = data[j]; + for (int k = 0; k < SK_ARRAY_COUNT(gProc1); ++k) { + IsFiniteProc1 proc1 = gProc1[k]; + + for (int m = 0; m < SK_ARRAY_COUNT(gProc2); ++m) { + bool finite = gProc2[m](rec0.fValue, rec1.fValue, proc1); + bool finite2 = rec0.fIsFinite && rec1.fIsFinite; + REPORTER_ASSERT(reporter, finite2 == finite); + } + } + } + } +#endif +} + +static void TestScalar(skiatest::Reporter* reporter) { + test_isfinite(reporter); +} + +#include "TestClassDef.h" +DEFINE_TESTCLASS("Scalar", TestScalarClass, TestScalar) + |