11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* 21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2011 Google Inc. 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * 41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file. 61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 81cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "Test.h" 91cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkFloatingPoint.h" 101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkMath.h" 111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkPoint.h" 121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkRandom.h" 131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_CAN_USE_FLOAT 151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool isFinite_int(float x) { 171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger uint32_t bits = SkFloat2Bits(x); // need unsigned for our shifts 181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int exponent = bits << 1 >> 24; 191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return exponent != 0xFF; 201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool isFinite_float(float x) { 231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return sk_float_isfinite(x); 241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool isFinite_mulzero(float x) { 271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger float y = x * 0; 281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return y == y; 291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// return true if the float is finite 321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergertypedef bool (*IsFiniteProc1)(float); 331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool isFinite2_and(float x, float y, IsFiniteProc1 proc) { 351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return proc(x) && proc(y); 361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool isFinite2_mulzeroadd(float x, float y, IsFiniteProc1 proc) { 391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return proc(x * 0 + y * 0); 401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// return true if both floats are finite 431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergertypedef bool (*IsFiniteProc2)(float, float, IsFiniteProc1); 441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerenum FloatClass { 481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger kFinite, 491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger kInfinite, 501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger kNaN 511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}; 521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void test_floatclass(skiatest::Reporter* reporter, float value, FloatClass fc) { 541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // our sk_float_is... function may return int instead of bool, 551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // hence the double ! to turn it into a bool 561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger REPORTER_ASSERT(reporter, !!sk_float_isfinite(value) == (fc == kFinite)); 571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger REPORTER_ASSERT(reporter, !!sk_float_isinf(value) == (fc == kInfinite)); 581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger REPORTER_ASSERT(reporter, !!sk_float_isnan(value) == (fc == kNaN)); 591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void test_isfinite(skiatest::Reporter* reporter) { 621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_CAN_USE_FLOAT 631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger struct Rec { 641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger float fValue; 651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool fIsFinite; 661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger }; 671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger float max = 3.402823466e+38f; 691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger float inf = max * max; 701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger float nan = inf * 0; 711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger test_floatclass(reporter, 0, kFinite); 731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger test_floatclass(reporter, max, kFinite); 741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger test_floatclass(reporter, -max, kFinite); 751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger test_floatclass(reporter, inf, kInfinite); 761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger test_floatclass(reporter, -inf, kInfinite); 771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger test_floatclass(reporter, nan, kNaN); 781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger test_floatclass(reporter, -nan, kNaN); 791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const Rec data[] = { 811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { 0, true }, 821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { 1, true }, 831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { -1, true }, 841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { max * 0.75, true }, 851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { max, true }, 861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { -max * 0.75, true }, 871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { -max, true }, 881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { inf, false }, 891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { -inf, false }, 901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { nan, false }, 911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger }; 921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const IsFiniteProc1 gProc1[] = { 941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger isFinite_int, 951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger isFinite_float, 961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger isFinite_mulzero 971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger }; 981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const IsFiniteProc2 gProc2[] = { 991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger isFinite2_and, 1001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger isFinite2_mulzeroadd 1011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger }; 1021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger size_t i, n = SK_ARRAY_COUNT(data); 1041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (i = 0; i < n; ++i) { 1061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (size_t k = 0; k < SK_ARRAY_COUNT(gProc1); ++k) { 1071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const Rec& rec = data[i]; 1081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool finite = gProc1[k](rec.fValue); 1091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger REPORTER_ASSERT(reporter, rec.fIsFinite == finite); 1101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (i = 0; i < n; ++i) { 1141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const Rec& rec0 = data[i]; 1151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (size_t j = 0; j < n; ++j) { 1161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const Rec& rec1 = data[j]; 1171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (size_t k = 0; k < SK_ARRAY_COUNT(gProc1); ++k) { 1181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger IsFiniteProc1 proc1 = gProc1[k]; 1191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (size_t m = 0; m < SK_ARRAY_COUNT(gProc2); ++m) { 1211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool finite = gProc2[m](rec0.fValue, rec1.fValue, proc1); 1221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool finite2 = rec0.fIsFinite && rec1.fIsFinite; 1231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger REPORTER_ASSERT(reporter, finite2 == finite); 1241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 1291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void TestScalar(skiatest::Reporter* reporter) { 1321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger test_isfinite(reporter); 1331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "TestClassDef.h" 1361cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerDEFINE_TESTCLASS("Scalar", TestScalarClass, TestScalar) 1371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 138