180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2006 The Android Open Source Project
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifndef Sk64_DEFINED
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define Sk64_DEFINED
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkFixed.h"
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** \class Sk64
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    Sk64 is a 64-bit math package that does not require long long support from the compiler.
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru*/
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustruct SK_API Sk64 {
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int32_t  fHi;   //!< the high 32 bits of the number (including sign)
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    uint32_t fLo;   //!< the low 32 bits of the number
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Returns non-zero if the Sk64 can be represented as a signed 32 bit integer
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkBool is32() const { return fHi == ((int32_t)fLo >> 31); }
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Returns non-zero if the Sk64 cannot be represented as a signed 32 bit integer
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkBool is64() const { return fHi != ((int32_t)fLo >> 31); }
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Returns non-zero if the Sk64 can be represented as a signed 48 bit integer. Used to know
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if we can shift the value down by 16 to treat it as a SkFixed.
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkBool isFixed() const;
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Return the signed 32 bit integer equivalent. Asserts that is32() returns non-zero.
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int32_t get32() const { SkASSERT(this->is32()); return (int32_t)fLo; }
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Return the number >> 16. Asserts that this does not loose any significant high bits.
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkFixed getFixed() const {
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(this->isFixed());
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        uint32_t sum = fLo + (1 << 15);
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int32_t  hi = fHi;
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (sum < fLo) {
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            hi += 1;
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return (hi << 16) | (sum >> 16);
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Return the number >> 30. Asserts that this does not loose any
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        significant high bits.
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkFract getFract() const;
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Returns the square-root of the number as a signed 32 bit value. */
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int32_t getSqrt() const;
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Returns the number of leading zeros of the absolute value of this.
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        Will return in the range [0..64]
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int getClzAbs() const;
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Returns non-zero if the number is zero */
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkBool  isZero() const { return (fHi | fLo) == 0; }
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Returns non-zero if the number is non-zero */
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkBool  nonZero() const { return fHi | fLo; }
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Returns non-zero if the number is negative (number < 0) */
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkBool  isNeg() const { return (uint32_t)fHi >> 31; }
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Returns non-zero if the number is positive (number > 0) */
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkBool  isPos() const { return ~(fHi >> 31) & (fHi | fLo); }
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Returns -1,0,+1 based on the sign of the number */
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int     getSign() const { return (fHi >> 31) | Sk32ToBool(fHi | fLo); }
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Negate the number */
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    negate();
8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** If the number < 0, negate the number
8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    abs();
8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Returns the number of bits needed to shift the Sk64 to the right
8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        in order to make it fit in a signed 32 bit integer.
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int     shiftToMake32() const;
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Set the number to zero */
9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    setZero() { fHi = fLo = 0; }
9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Set the high and low 32 bit values of the number */
9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    set(int32_t hi, uint32_t lo) { fHi = hi; fLo = lo; }
9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Set the number to the specified 32 bit integer */
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    set(int32_t a) { fHi = a >> 31; fLo = a; }
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Set the number to the product of the two 32 bit integers */
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    setMul(int32_t a, int32_t b);
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** extract 32bits after shifting right by bitCount.
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        Note: itCount must be [0..63].
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        Asserts that no significant high bits were lost.
10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int32_t getShiftRight(unsigned bitCount) const;
11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Shift the number left by the specified number of bits.
11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        @param bits How far to shift left, must be [0..63]
11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    shiftLeft(unsigned bits);
11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Shift the number right by the specified number of bits.
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        @param bits How far to shift right, must be [0..63]. This
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        performs an arithmetic right-shift (sign extending).
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    shiftRight(unsigned bits);
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Shift the number right by the specified number of bits, but
12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        round the result.
12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        @param bits How far to shift right, must be [0..63]. This
12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        performs an arithmetic right-shift (sign extending).
12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    roundRight(unsigned bits);
12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Add the specified 32 bit integer to the number */
13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void add(int32_t lo) {
13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int32_t  hi = lo >> 31; // 0 or -1
13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        uint32_t sum = fLo + (uint32_t)lo;
13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fHi = fHi + hi + (sum < fLo);
13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fLo = sum;
13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Add the specified Sk64 to the number */
13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void add(int32_t hi, uint32_t lo) {
14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        uint32_t sum = fLo + lo;
14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fHi = fHi + hi + (sum < fLo);
14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fLo = sum;
14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Add the specified Sk64 to the number */
14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    add(const Sk64& other) { this->add(other.fHi, other.fLo); }
14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Subtract the specified Sk64 from the number. (*this) = (*this) - num
15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    sub(const Sk64& num);
15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Subtract the number from the specified Sk64. (*this) = num - (*this)
15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    rsub(const Sk64& num);
15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Multiply the number by the specified 32 bit integer
15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    mul(int32_t);
16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    enum DivOptions {
16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kTrunc_DivOption,   //!< truncate the result when calling div()
16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kRound_DivOption    //!< round the result when calling div()
16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    };
16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Divide the number by the specified 32 bit integer, using the specified
16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        divide option (either truncate or round).
16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    div(int32_t, DivOptions);
17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** return (this + other >> 16) as a 32bit result */
17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkFixed addGetFixed(const Sk64& other) const {
17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return this->addGetFixed(other.fHi, other.fLo);
17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** return (this + Sk64(hi, lo) >> 16) as a 32bit result */
17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkFixed addGetFixed(int32_t hi, uint32_t lo) const {
17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DEBUG
17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        Sk64    tmp(*this);
18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        tmp.add(hi, lo);
18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        uint32_t sum = fLo + lo;
18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        hi += fHi + (sum < fLo);
18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        lo = sum;
18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        sum = lo + (1 << 15);
18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (sum < lo)
18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            hi += 1;
19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        hi = (hi << 16) | (sum >> 16);
19280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(hi == tmp.getFixed());
19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return hi;
19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Return the result of dividing the number by denom, treating the answer
19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        as a SkFixed. (*this) << 16 / denom. It is an error for denom to be 0.
19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkFixed getFixedDiv(const Sk64& denom) const;
20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    friend bool operator==(const Sk64& a, const Sk64& b) {
20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return a.fHi == b.fHi && a.fLo == b.fLo;
20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    friend bool operator!=(const Sk64& a, const Sk64& b) {
20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return a.fHi != b.fHi || a.fLo != b.fLo;
20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    friend bool operator<(const Sk64& a, const Sk64& b) {
21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return a.fHi < b.fHi || (a.fHi == b.fHi && a.fLo < b.fLo);
21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    friend bool operator<=(const Sk64& a, const Sk64& b) {
21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return a.fHi < b.fHi || (a.fHi == b.fHi && a.fLo <= b.fLo);
21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    friend bool operator>(const Sk64& a, const Sk64& b) {
21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return a.fHi > b.fHi || (a.fHi == b.fHi && a.fLo > b.fLo);
21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
22180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    friend bool operator>=(const Sk64& a, const Sk64& b) {
22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return a.fHi > b.fHi || (a.fHi == b.fHi && a.fLo >= b.fLo);
22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SkLONGLONG
22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkLONGLONG getLongLong() const;
22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
22980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
23080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
231