blob: 2848516b97b1e367f4831d6a40b94a42185f497b [file] [log] [blame]
reed@google.comd230e3e2011-12-05 20:49:37 +00001/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "Test.h"
9#include "SkFloatingPoint.h"
10#include "SkMath.h"
11#include "SkPoint.h"
12#include "SkRandom.h"
13
14#ifdef SK_CAN_USE_FLOAT
15
16static bool isFinite_int(float x) {
17 uint32_t bits = SkFloat2Bits(x); // need unsigned for our shifts
18 int exponent = bits << 1 >> 24;
19 return exponent != 0xFF;
20}
21
22static bool isFinite_float(float x) {
23 return isfinite(x);
24}
25
26static bool isFinite_mulzero(float x) {
27 float y = x * 0;
28 return y == y;
29}
30
31// return true if the float is finite
32typedef bool (*IsFiniteProc1)(float);
33
34static bool isFinite2_and(float x, float y, IsFiniteProc1 proc) {
35 return proc(x) && proc(y);
36}
37
38static bool isFinite2_mulzeroadd(float x, float y, IsFiniteProc1 proc) {
39 return proc(x * 0 + y * 0);
40}
41
42// return true if both floats are finite
43typedef bool (*IsFiniteProc2)(float, float, IsFiniteProc1);
44
45#endif
46
47static void test_isfinite(skiatest::Reporter* reporter) {
48#ifdef SK_CAN_USE_FLOAT
49 struct Rec {
50 float fValue;
51 bool fIsFinite;
52 };
53
54 float max = 3.402823466e+38f;
55 float inf = max * max;
56 float nan = 1 / sk_float_sin(0);
57
58 const Rec data[] = {
59 { 0, true },
60 { 1, true },
61 { -1, true },
62 { max * 0.75, true },
63 { max, true },
64 { -max * 0.75, true },
65 { -max, true },
66 { inf, false },
67 { -inf, false },
68 { nan, false },
69 };
70
71 const IsFiniteProc1 gProc1[] = {
72 isFinite_int,
73 isFinite_float,
74 isFinite_mulzero
75 };
76 const IsFiniteProc2 gProc2[] = {
77 isFinite2_and,
78 isFinite2_mulzeroadd
79 };
80
81 int i, n = SK_ARRAY_COUNT(data);
82
83 for (i = 0; i < n; ++i) {
84 for (int k = 0; k < SK_ARRAY_COUNT(gProc1); ++k) {
85 const Rec& rec = data[i];
86 bool finite = gProc1[k](rec.fValue);
87 REPORTER_ASSERT(reporter, rec.fIsFinite == finite);
88 }
89 }
90
91 for (i = 0; i < n; ++i) {
92 const Rec& rec0 = data[i];
93 for (int j = 0; j < n; ++j) {
94 const Rec& rec1 = data[j];
95 for (int k = 0; k < SK_ARRAY_COUNT(gProc1); ++k) {
96 IsFiniteProc1 proc1 = gProc1[k];
97
98 for (int m = 0; m < SK_ARRAY_COUNT(gProc2); ++m) {
99 bool finite = gProc2[m](rec0.fValue, rec1.fValue, proc1);
100 bool finite2 = rec0.fIsFinite && rec1.fIsFinite;
101 REPORTER_ASSERT(reporter, finite2 == finite);
102 }
103 }
104 }
105 }
106#endif
107}
108
109static void TestScalar(skiatest::Reporter* reporter) {
110 test_isfinite(reporter);
111}
112
113#include "TestClassDef.h"
114DEFINE_TESTCLASS("Scalar", TestScalarClass, TestScalar)
115