11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2011 Google Inc. 41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * 51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file. 71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 8da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#include "Test.h" 9da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#include "SkRandom.h" 10da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#include <math.h> 11da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 12da3b8b285a5e3e6f344461d67e3370b27701756dMike Reedstruct BoolTable { 13da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed int8_t zero, pos, neg, toBool, sign; 14da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed}; 15da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 16da3b8b285a5e3e6f344461d67e3370b27701756dMike Reedstatic void bool_table_test(skiatest::Reporter* reporter, 17da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed const Sk64& a, const BoolTable& table) 18da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed{ 19da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, a.isZero() != a.nonZero()); 20da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 21da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, !a.isZero() == !table.zero); 22da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, !a.isPos() == !table.pos); 23da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, !a.isNeg() == !table.neg); 24da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, a.getSign() == table.sign); 25da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed} 26da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 27da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#ifdef SkLONGLONG 28da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed static SkLONGLONG asLL(const Sk64& a) 29da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed { 30da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed return ((SkLONGLONG)a.fHi << 32) | a.fLo; 31da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed } 32da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#endif 33da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 34da3b8b285a5e3e6f344461d67e3370b27701756dMike Reedstatic void TestSk64(skiatest::Reporter* reporter) { 35da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed enum BoolTests { 36da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed kZero_BoolTest, 37da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed kPos_BoolTest, 38da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed kNeg_BoolTest 39da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed }; 40da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed static const BoolTable gBoolTable[] = { 41da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed { 1, 0, 0, 0, 0 }, 42da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed { 0, 1, 0, 1, 1 }, 43da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed { 0, 0, 1, 1, -1 } 44da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed }; 45da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 46da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed Sk64 a, b, c; 47da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 48da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed a.fHi = a.fLo = 0; 49da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed b.set(0); 50da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed c.setZero(); 51da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, a == b); 52da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, a == c); 53da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed bool_table_test(reporter, a, gBoolTable[kZero_BoolTest]); 54da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 55da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed a.fHi = 0; a.fLo = 5; 56da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed b.set(5); 57da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, a == b); 58da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, a.is32() && a.get32() == 5 && !a.is64()); 59da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed bool_table_test(reporter, a, gBoolTable[kPos_BoolTest]); 60da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 61da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed a.fHi = -1; a.fLo = (uint32_t)-5; 62da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed b.set(-5); 63da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, a == b); 64da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, a.is32() && a.get32() == -5 && !a.is64()); 65da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed bool_table_test(reporter, a, gBoolTable[kNeg_BoolTest]); 66da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 67da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed a.setZero(); 68da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed b.set(6); 69da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed c.set(-6); 70da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, a != b && b != c && a != c); 71da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, !(a == b) && !(a == b) && !(a == b)); 72da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, a < b && b > a && a <= b && b >= a); 73da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, c < a && a > c && c <= a && a >= c); 74da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, c < b && b > c && c <= b && b >= c); 75da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 76da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed // Now test add/sub 77da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 78da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkRandom rand; 79da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed int i; 80da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 81da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed for (i = 0; i < 1000; i++) 82da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed { 83da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed int aa = rand.nextS() >> 1; 84da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed int bb = rand.nextS() >> 1; 85da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed a.set(aa); 86da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed b.set(bb); 87da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, a.get32() == aa && b.get32() == bb); 88da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed c = a; c.add(bb); 89da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, c.get32() == aa + bb); 90da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed c = a; c.add(-bb); 91da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, c.get32() == aa - bb); 92da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed c = a; c.add(b); 93da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, c.get32() == aa + bb); 94da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed c = a; c.sub(b); 95da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, c.get32() == aa - bb); 96da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed } 97da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 98da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#ifdef SkLONGLONG 99da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed for (i = 0; i < 1000; i++) 100da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed { 101da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed rand.next64(&a); //a.fHi >>= 1; // avoid overflow 102da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed rand.next64(&b); //b.fHi >>= 1; // avoid overflow 103da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 104da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed if (!(i & 3)) // want to explicitly test these cases 105da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed { 106da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed a.fLo = 0; 107da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed b.fLo = 0; 108da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed } 109da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed else if (!(i & 7)) // want to explicitly test these cases 110da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed { 111da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed a.fHi = 0; 112da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed b.fHi = 0; 113da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed } 114da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 115da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkLONGLONG aa = asLL(a); 116da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkLONGLONG bb = asLL(b); 117da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 118da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, (a < b) == (aa < bb)); 119da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, (a <= b) == (aa <= bb)); 120da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, (a > b) == (aa > bb)); 121da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, (a >= b) == (aa >= bb)); 122da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, (a == b) == (aa == bb)); 123da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, (a != b) == (aa != bb)); 124da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 125da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed c = a; c.add(b); 126da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, asLL(c) == aa + bb); 127da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed c = a; c.sub(b); 128da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, asLL(c) == aa - bb); 129da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed c = a; c.rsub(b); 130da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, asLL(c) == bb - aa); 131da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed c = a; c.negate(); 132da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, asLL(c) == -aa); 133da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 134da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed int bits = rand.nextU() & 63; 135da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed c = a; c.shiftLeft(bits); 136da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, asLL(c) == (aa << bits)); 137da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed c = a; c.shiftRight(bits); 138da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, asLL(c) == (aa >> bits)); 139da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed c = a; c.roundRight(bits); 140da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 141da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkLONGLONG tmp; 142da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 143da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed tmp = aa; 144da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed if (bits > 0) 145da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed tmp += (SkLONGLONG)1 << (bits - 1); 146da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, asLL(c) == (tmp >> bits)); 147da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 148da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed c.setMul(a.fHi, b.fHi); 149da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed tmp = (SkLONGLONG)a.fHi * b.fHi; 150da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, asLL(c) == tmp); 151da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed } 152da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 153da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 154da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed for (i = 0; i < 100000; i++) 155da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed { 156da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed Sk64 wide; 157da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed int32_t denom = rand.nextS(); 158da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 159da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed while (denom == 0) 160da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed denom = rand.nextS(); 161da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed wide.setMul(rand.nextS(), rand.nextS()); 162da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkLONGLONG check = wide.getLongLong(); 163da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 164da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed wide.div(denom, Sk64::kTrunc_DivOption); 165da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed check /= denom; 166da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkLONGLONG w = wide.getLongLong(); 167da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 168da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, check == w); 169da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 170da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#ifdef SK_CAN_USE_FLOAT 171da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed wide.setMul(rand.nextS(), rand.nextS()); 172da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed wide.abs(); 173da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed denom = wide.getSqrt(); 174da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed int32_t ck = (int32_t)sqrt((double)wide.getLongLong()); 175da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed int diff = denom - ck; 176da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, SkAbs32(diff) <= 1); 177da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 178da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed wide.setMul(rand.nextS(), rand.nextS()); 179da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed Sk64 dwide; 180da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed dwide.setMul(rand.nextS(), rand.nextS()); 181da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkFixed fixdiv = wide.getFixedDiv(dwide); 182da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed double dnumer = (double)wide.getLongLong(); 183da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed double ddenom = (double)dwide.getLongLong(); 184da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed double ddiv = dnumer / ddenom; 185da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkFixed dfixdiv; 186da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed if (ddiv >= (double)SK_MaxS32 / (double)SK_Fixed1) 187da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed dfixdiv = SK_MaxS32; 188da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed else if (ddiv <= -(double)SK_MaxS32 / (double)SK_Fixed1) 189da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed dfixdiv = SK_MinS32; 190da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed else 191da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed dfixdiv = SkFloatToFixed(dnumer / ddenom); 192da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed diff = fixdiv - dfixdiv; 193da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 194da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed if (SkAbs32(diff) > 1) { 195da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkDebugf(" %d === numer %g denom %g div %g xdiv %x fxdiv %x\n", 196da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed i, dnumer, ddenom, ddiv, dfixdiv, fixdiv); 197da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed } 198da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, SkAbs32(diff) <= 1); 199da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#endif 200da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed } 201da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#endif 202da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed} 203da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 204da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#include "TestClassDef.h" 205da3b8b285a5e3e6f344461d67e3370b27701756dMike ReedDEFINE_TESTCLASS("Sk64", Sk64TestClass, TestSk64) 206