00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef Sk64_DEFINED
00018 #define Sk64_DEFINED
00019
00020 #include "SkFixed.h"
00021 #include "SkMath.h"
00022
00027 struct Sk64 {
00028 int32_t fHi;
00029 uint32_t fLo;
00030
00033 SkBool is32() const { return fHi == ((int32_t)fLo >> 31); }
00034
00037 SkBool is64() const { return fHi != ((int32_t)fLo >> 31); }
00038
00042 SkBool isFixed() const;
00043
00046 int32_t get32() const { SkASSERT(this->is32()); return (int32_t)fLo; }
00047
00050 SkFixed getFixed() const {
00051 SkASSERT(this->isFixed());
00052
00053 uint32_t sum = fLo + (1 << 15);
00054 int32_t hi = fHi;
00055 if (sum < fLo) {
00056 hi += 1;
00057 }
00058 return (hi << 16) | (sum >> 16);
00059 }
00060
00064 SkFract getFract() const;
00065
00067 int32_t getSqrt() const;
00068
00072 int getClzAbs() const;
00073
00075 SkBool isZero() const { return (fHi | fLo) == 0; }
00076
00078 SkBool nonZero() const { return fHi | fLo; }
00079
00081 SkBool isNeg() const { return (uint32_t)fHi >> 31; }
00082
00084 SkBool isPos() const { return ~(fHi >> 31) & (fHi | fLo); }
00085
00087 int getSign() const { return (fHi >> 31) | Sk32ToBool(fHi | fLo); }
00088
00090 void negate();
00091
00094 void abs();
00095
00099 int shiftToMake32() const;
00100
00102 void setZero() { fHi = fLo = 0; }
00103
00105 void set(int32_t hi, uint32_t lo) { fHi = hi; fLo = lo; }
00106
00108 void set(int32_t a) { fHi = a >> 31; fLo = a; }
00109
00111 void setMul(int32_t a, int32_t b);
00112
00117 int32_t getShiftRight(unsigned bitCount) const;
00118
00122 void shiftLeft(unsigned bits);
00123
00128 void shiftRight(unsigned bits);
00129
00135 void roundRight(unsigned bits);
00136
00138 void add(int32_t lo) {
00139 int32_t hi = lo >> 31;
00140 uint32_t sum = fLo + (uint32_t)lo;
00141
00142 fHi = fHi + hi + (sum < fLo);
00143 fLo = sum;
00144 }
00145
00147 void add(int32_t hi, uint32_t lo) {
00148 uint32_t sum = fLo + lo;
00149
00150 fHi = fHi + hi + (sum < fLo);
00151 fLo = sum;
00152 }
00153
00155 void add(const Sk64& other) { this->add(other.fHi, other.fLo); }
00156
00159 void sub(const Sk64& num);
00160
00163 void rsub(const Sk64& num);
00164
00167 void mul(int32_t);
00168
00169 enum DivOptions {
00170 kTrunc_DivOption,
00171 kRound_DivOption
00172 };
00173
00177 void div(int32_t, DivOptions);
00178
00180 SkFixed addGetFixed(const Sk64& other) const {
00181 return this->addGetFixed(other.fHi, other.fLo);
00182 }
00183
00185 SkFixed addGetFixed(int32_t hi, uint32_t lo) const {
00186 #ifdef SK_DEBUG
00187 Sk64 tmp(*this);
00188 tmp.add(hi, lo);
00189 #endif
00190
00191 uint32_t sum = fLo + lo;
00192 hi += fHi + (sum < fLo);
00193 lo = sum;
00194
00195 sum = lo + (1 << 15);
00196 if (sum < lo)
00197 hi += 1;
00198
00199 hi = (hi << 16) | (sum >> 16);
00200 SkASSERT(hi == tmp.getFixed());
00201 return hi;
00202 }
00203
00207 SkFixed getFixedDiv(const Sk64& denom) const;
00208
00209 friend bool operator==(const Sk64& a, const Sk64& b) {
00210 return a.fHi == b.fHi && a.fLo == b.fLo;
00211 }
00212
00213 friend bool operator!=(const Sk64& a, const Sk64& b) {
00214 return a.fHi != b.fHi || a.fLo != b.fLo;
00215 }
00216
00217 friend bool operator<(const Sk64& a, const Sk64& b) {
00218 return a.fHi < b.fHi || (a.fHi == b.fHi && a.fLo < b.fLo);
00219 }
00220
00221 friend bool operator<=(const Sk64& a, const Sk64& b) {
00222 return a.fHi < b.fHi || (a.fHi == b.fHi && a.fLo <= b.fLo);
00223 }
00224
00225 friend bool operator>(const Sk64& a, const Sk64& b) {
00226 return a.fHi > b.fHi || (a.fHi == b.fHi && a.fLo > b.fLo);
00227 }
00228
00229 friend bool operator>=(const Sk64& a, const Sk64& b) {
00230 return a.fHi > b.fHi || (a.fHi == b.fHi && a.fLo >= b.fLo);
00231 }
00232
00233 #ifdef SkLONGLONG
00234 SkLONGLONG getLongLong() const;
00235 #endif
00236 };
00237
00238 #endif
00239