1 /* 2 * Copyright 2012 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 #include "DataTypes.h" 8 9 #include <sys/types.h> 10 #include <stdlib.h> 11 12 #if USE_EPSILON 13 const double PointEpsilon = 0.000001; 14 const double SquaredEpsilon = PointEpsilon * PointEpsilon; 15 #endif 16 17 const int UlpsEpsilon = 16; 18 19 _Vector operator-(const _Point& a, const _Point& b) { 20 _Vector v = {a.x - b.x, a.y - b.y}; 21 return v; 22 } 23 24 _Point operator+(const _Point& a, const _Vector& b) { 25 _Point v = {a.x + b.x, a.y + b.y}; 26 return v; 27 } 28 29 // from http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ 30 union Float_t 31 { 32 Float_t(float num = 0.0f) : f(num) {} 33 // Portable extraction of components. 34 bool negative() const { return (i >> 31) != 0; } 35 #if 0 // unused 36 int32_t RawMantissa() const { return i & ((1 << 23) - 1); } 37 int32_t RawExponent() const { return (i >> 23) & 0xFF; } 38 #endif 39 int32_t i; 40 float f; 41 #ifdef SK_DEBUG 42 struct 43 { // Bitfields for exploration. Do not use in production code. 44 uint32_t mantissa : 23; 45 uint32_t exponent : 8; 46 uint32_t sign : 1; 47 } parts; 48 #endif 49 }; 50 51 bool AlmostEqualUlps(float A, float B) 52 { 53 Float_t uA(A); 54 Float_t uB(B); 55 56 // Different signs means they do not match. 57 if (uA.negative() != uB.negative()) 58 { 59 // Check for equality to make sure +0==-0 60 return A == B; 61 } 62 63 // Find the difference in ULPs. 64 int ulpsDiff = abs(uA.i - uB.i); 65 return ulpsDiff <= UlpsEpsilon; 66 } 67 68 // FIXME: obsolete, delete 69 #if 1 70 int UlpsDiff(float A, float B) 71 { 72 Float_t uA(A); 73 Float_t uB(B); 74 75 return abs(uA.i - uB.i); 76 } 77 #endif 78 79 #ifdef SK_DEBUG 80 void mathematica_ize(char* str, size_t bufferLen) { 81 size_t len = strlen(str); 82 bool num = false; 83 for (size_t idx = 0; idx < len; ++idx) { 84 if (num && str[idx] == 'e') { 85 if (len + 2 >= bufferLen) { 86 return; 87 } 88 memmove(&str[idx + 2], &str[idx + 1], len - idx); 89 str[idx] = '*'; 90 str[idx + 1] = '^'; 91 ++len; 92 } 93 num = str[idx] >= '0' && str[idx] <= '9'; 94 } 95 } 96 97 bool valid_wind(int wind) { 98 return wind > SK_MinS32 + 0xFFFF && wind < SK_MaxS32 - 0xFFFF; 99 } 100 101 void winding_printf(int wind) { 102 if (wind == SK_MinS32) { 103 SkDebugf("?"); 104 } else { 105 SkDebugf("%d", wind); 106 } 107 } 108 #endif 109