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
operator -(const _Point & a,const _Point & b)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
operator +(const _Point & a,const _Vector & b)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 {
Float_t(float num=0.0f)32 Float_t(float num = 0.0f) : f(num) {}
33 // Portable extraction of components.
negative() const34 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 #if 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
AlmostEqualUlps(float A,float B)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
UlpsDiff(float A,float B)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 #if SK_DEBUG
mathematica_ize(char * str,size_t bufferLen)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
valid_wind(int wind)97 bool valid_wind(int wind) {
98 return wind > SK_MinS32 + 0xFFFF && wind < SK_MaxS32 - 0xFFFF;
99 }
100
winding_printf(int wind)101 void winding_printf(int wind) {
102 if (wind == SK_MinS32) {
103 SkDebugf("?");
104 } else {
105 SkDebugf("%d", wind);
106 }
107 }
108 #endif
109