OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2006 The Android Open Source Project | |
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 #ifndef Sk64_DEFINED | |
9 #define Sk64_DEFINED | |
10 | |
11 #include "SkTypes.h" | |
12 | |
13 /** \class Sk64 | |
14 | |
15 Sk64 is a 64-bit math package that does not require long long support from t
he compiler. | |
16 */ | |
17 struct SK_API Sk64 { | |
18 private: | |
19 int32_t fHi; //!< the high 32 bits of the number (including sign) | |
20 uint32_t fLo; //!< the low 32 bits of the number | |
21 | |
22 public: | |
23 int32_t hi() const { return fHi; } | |
24 uint32_t lo() const { return fLo; } | |
25 | |
26 int64_t as64() const { return ((int64_t)fHi << 32) | fLo; } | |
27 int64_t getLongLong() const { return this->as64(); } | |
28 | |
29 void set64(int64_t value) { | |
30 fHi = (int32_t)(value >> 32); | |
31 fLo = (uint32_t)value; | |
32 } | |
33 | |
34 /** Returns non-zero if the Sk64 can be represented as a signed 32 bit integ
er | |
35 */ | |
36 SkBool is32() const { return fHi == ((int32_t)fLo >> 31); } | |
37 | |
38 /** Returns non-zero if the Sk64 cannot be represented as a signed 32 bit in
teger | |
39 */ | |
40 SkBool is64() const { return fHi != ((int32_t)fLo >> 31); } | |
41 | |
42 /** Return the signed 32 bit integer equivalent. Asserts that is32() returns
non-zero. | |
43 */ | |
44 int32_t get32() const { SkASSERT(this->is32()); return (int32_t)fLo; } | |
45 | |
46 /** Returns the square-root of the number as a signed 32 bit value. */ | |
47 int32_t getSqrt() const; | |
48 | |
49 /** Returns the number of leading zeros of the absolute value of this. | |
50 Will return in the range [0..64] | |
51 */ | |
52 int getClzAbs() const; | |
53 | |
54 /** Returns non-zero if the number is zero */ | |
55 SkBool isZero() const { return (fHi | fLo) == 0; } | |
56 | |
57 /** Returns non-zero if the number is non-zero */ | |
58 SkBool nonZero() const { return fHi | fLo; } | |
59 | |
60 /** Returns non-zero if the number is negative (number < 0) */ | |
61 SkBool isNeg() const { return (uint32_t)fHi >> 31; } | |
62 | |
63 /** Returns non-zero if the number is positive (number > 0) */ | |
64 SkBool isPos() const { return ~(fHi >> 31) & (fHi | fLo); } | |
65 | |
66 /** Returns -1,0,+1 based on the sign of the number */ | |
67 int getSign() const { return (fHi >> 31) | Sk32ToBool(fHi | fLo); } | |
68 | |
69 /** Negate the number */ | |
70 void negate(); | |
71 | |
72 /** If the number < 0, negate the number | |
73 */ | |
74 void abs(); | |
75 | |
76 /** Returns the number of bits needed to shift the Sk64 to the right | |
77 in order to make it fit in a signed 32 bit integer. | |
78 */ | |
79 int shiftToMake32() const; | |
80 | |
81 /** Set the number to zero */ | |
82 void setZero() { fHi = fLo = 0; } | |
83 | |
84 /** Set the high and low 32 bit values of the number */ | |
85 void set(int32_t hi, uint32_t lo) { fHi = hi; fLo = lo; } | |
86 | |
87 /** Set the number to the specified 32 bit integer */ | |
88 void set(int32_t a) { fHi = a >> 31; fLo = a; } | |
89 | |
90 /** Set the number to the product of the two 32 bit integers */ | |
91 void setMul(int32_t a, int32_t b); | |
92 | |
93 /** extract 32bits after shifting right by bitCount. | |
94 Note: itCount must be [0..63]. | |
95 Asserts that no significant high bits were lost. | |
96 */ | |
97 int32_t getShiftRight(unsigned bitCount) const; | |
98 | |
99 /** Shift the number left by the specified number of bits. | |
100 @param bits How far to shift left, must be [0..63] | |
101 */ | |
102 void shiftLeft(unsigned bits); | |
103 | |
104 /** Shift the number right by the specified number of bits. | |
105 @param bits How far to shift right, must be [0..63]. This | |
106 performs an arithmetic right-shift (sign extending). | |
107 */ | |
108 void shiftRight(unsigned bits); | |
109 | |
110 /** Shift the number right by the specified number of bits, but | |
111 round the result. | |
112 @param bits How far to shift right, must be [0..63]. This | |
113 performs an arithmetic right-shift (sign extending). | |
114 */ | |
115 void roundRight(unsigned bits); | |
116 | |
117 /** Add the specified 32 bit integer to the number */ | |
118 void add(int32_t lo) { | |
119 int32_t hi = lo >> 31; // 0 or -1 | |
120 uint32_t sum = fLo + (uint32_t)lo; | |
121 | |
122 fHi = fHi + hi + (sum < fLo); | |
123 fLo = sum; | |
124 } | |
125 | |
126 /** Add the specified Sk64 to the number */ | |
127 void add(int32_t hi, uint32_t lo) { | |
128 uint32_t sum = fLo + lo; | |
129 | |
130 fHi = fHi + hi + (sum < fLo); | |
131 fLo = sum; | |
132 } | |
133 | |
134 /** Add the specified Sk64 to the number */ | |
135 void add(const Sk64& other) { this->add(other.fHi, other.fLo); } | |
136 | |
137 /** Subtract the specified Sk64 from the number. (*this) = (*this) - num | |
138 */ | |
139 void sub(const Sk64& num); | |
140 | |
141 /** Subtract the number from the specified Sk64. (*this) = num - (*this) | |
142 */ | |
143 void rsub(const Sk64& num); | |
144 | |
145 /** Multiply the number by the specified 32 bit integer | |
146 */ | |
147 void mul(int32_t); | |
148 | |
149 enum DivOptions { | |
150 kTrunc_DivOption, //!< truncate the result when calling div() | |
151 kRound_DivOption //!< round the result when calling div() | |
152 }; | |
153 | |
154 /** Divide the number by the specified 32 bit integer, using the specified | |
155 divide option (either truncate or round). | |
156 */ | |
157 void div(int32_t, DivOptions); | |
158 | |
159 friend bool operator==(const Sk64& a, const Sk64& b) { | |
160 return a.fHi == b.fHi && a.fLo == b.fLo; | |
161 } | |
162 | |
163 friend bool operator!=(const Sk64& a, const Sk64& b) { | |
164 return a.fHi != b.fHi || a.fLo != b.fLo; | |
165 } | |
166 | |
167 friend bool operator<(const Sk64& a, const Sk64& b) { | |
168 return a.fHi < b.fHi || (a.fHi == b.fHi && a.fLo < b.fLo); | |
169 } | |
170 | |
171 friend bool operator<=(const Sk64& a, const Sk64& b) { | |
172 return a.fHi < b.fHi || (a.fHi == b.fHi && a.fLo <= b.fLo); | |
173 } | |
174 | |
175 friend bool operator>(const Sk64& a, const Sk64& b) { | |
176 return a.fHi > b.fHi || (a.fHi == b.fHi && a.fLo > b.fLo); | |
177 } | |
178 | |
179 friend bool operator>=(const Sk64& a, const Sk64& b) { | |
180 return a.fHi > b.fHi || (a.fHi == b.fHi && a.fLo >= b.fLo); | |
181 } | |
182 | |
183 // Private to unittests. Parameter is (skiatest::Reporter*) | |
184 static void UnitTestWithReporter(void* skiatest_reporter); | |
185 }; | |
186 | |
187 #endif | |
OLD | NEW |