#ifndef __ANTARESDAQ__ULONGLONG__ #define __ANTARESDAQ__ULONGLONG__ #include #include #include #include #include class ulonglong { typedef unsigned int uint; public: uint u1; uint u2; public: /** * Default contructor. */ ulonglong() : u1(0), u2(0) {} /** * Constructor. * \param u1_ most significant value * \param u2_ least significant value */ ulonglong(const uint u1_,const uint u2_) : u1(u1_), u2(u2_) {} /** * Constructor. * \param u2_ least significant value */ ulonglong(const int u2_) : u1(0), u2(u2_) {} /** * Constructor. * \param u2_ least significant value */ ulonglong(const uint u2_) : u1(0), u2(u2_) {} /** * Constructor. * \param d value */ ulonglong(const double d) : u1(0), u2(0) { *this = d; } /** * Assignment operator */ ulonglong& operator=(const int i) { u1 = 0; u2 = (uint) i; return *this; } /** * Assignment operator */ ulonglong& operator=(const uint i) { u1 = 0; u2 = i; return *this; } /** * Assignment operator */ ulonglong& operator=(const double d) { if (d < (double) std::numeric_limits::max()) { u1 = 0; u2 = (uint) d; } else { u1 = (uint) (d / ((double) std::numeric_limits::max())); u2 = (uint) (d - ((double) u1) * (double) std::numeric_limits::max()); } return *this; } /** * cast operator */ operator double() const { return ((double) u1) * ((double) std::numeric_limits::max()) + ((double) u2); } /** * prefix decrement */ ulonglong& operator--() { if (u2 > 0) --u2; else { --u1; u2 = std::numeric_limits::max(); } return *this; } /** * prefix increment */ ulonglong& operator++() { if (u2 < std::numeric_limits::max()) ++u2; else { ++u1; u2 = 0; } return *this; } /** * postfix decrement */ ulonglong operator--(int) { ulonglong a(*this); if (u2 > 0) u2--; else { u1--; u2 = std::numeric_limits::max(); } return a; } /** * postfix increment */ ulonglong operator++(int) { ulonglong a(*this); if (u2 < std::numeric_limits::max()) u2++; else { u1++; u2 = 0; } return a; } ulonglong operator-(const int x) { ulonglong b(*this); b -= x; return b; } ulonglong operator+(const int x) { ulonglong b(*this); b += x; return b; } ulonglong operator-(const ulonglong& b) { ulonglong a(*this); a.u1 -= b.u1; return (a -= b.u2); } ulonglong operator+(const ulonglong& b) { ulonglong a(*this); a.u1 += b.u1; return (a += b.u2); } ulonglong& operator+=(const int x) { if (x >= 0) return (*this += (uint) x); else return (*this -= (uint) -x); } ulonglong& operator-=(const int x) { if (x >= 0) return (*this -= (uint) x); else return (*this += (uint) -x); } ulonglong& operator+=(const uint x) { uint l = std::numeric_limits::max() - u2; if (l >= x) u2 += x; else { u1++; u2 = x - l - 1; } return *this; } ulonglong& operator-=(const uint x) { if (u2 >= x) u2 -= x; else { u1--; u2 = (std::numeric_limits::max() - x) + u2 + 1; } return *this; } ulonglong& operator-=(const ulonglong& x) { u1 -= x.u1; *this -= x.u2; return *this; } ulonglong& operator+=(const ulonglong& x) { *this += x.u2; u1 += x.u1; return *this; } ulonglong& operator&=(const ulonglong& x) { u1 &= x.u1; u2 &= x.u2; return *this; } ulonglong& operator|=(const ulonglong& x) { u1 |= x.u1; u2 |= x.u2; return *this; } ulonglong& operator^=(const ulonglong& x) { u1 ^= x.u1; u2 ^= x.u2; return *this; } bool operator==(const ulonglong& b) const { return (u1 == b.u1 && u2 == b.u2); } bool operator!=(const ulonglong& b) const { return (u1 != b.u1 || u2 != b.u2); } bool operator<(const ulonglong& b) const { if (u1 == b.u1) return (u2 < b.u2); else return (u1 < b.u1); } bool operator<=(const ulonglong& b) const { if (u1 == b.u1) return (u2 <= b.u2); else return (u1 <= b.u1); } bool operator>(const ulonglong& b) const { if (u1 == b.u1) return (u2 > b.u2); else return (u1 > b.u1); } bool operator>=(const ulonglong& b) const { if (u1 == b.u1) return (u2 >= b.u2); else return (u1 >= b.u1); } uint operator[](const int i) { assert(i == 0 || i == 1); if (i == 0) return u1; else return u2; } uint msw() const { return u1; } //!< most significant value uint lsw() const { return u2; } //!< least significant value std::ostream& write(std::ostream& out) const { std::ios::fmtflags oldFlags = out.flags(); out << std::hex << std::setfill('0') << std::setw(8) << u1 << std::setw(8) << u2; out.flags(oldFlags); return out; } std::istream& read(std::istream& in) { in >> u1 >> u2; return in; } /** * distance between 2 values * \param a first value * \param b second value * \return distance */ static ulonglong distance(const ulonglong& a, const ulonglong& b) { ulonglong value; value.u1 = std::max(a.u1,b.u1) - std::min(a.u1,b.u1); value.u2 = std::max(a.u2,b.u2) - std::min(a.u2,b.u2); if ((a.u1 < b.u1 && a.u2 > b.u2) || (a.u1 > b.u1 && a.u2 < b.u2)) { --value.u1; value.u2 = std::numeric_limits::max() - value.u2 + 1; } return value; } }; inline ulonglong operator&(const ulonglong& a, const ulonglong& b) { ulonglong c(a); return c&=b; } inline ulonglong operator|(const ulonglong& a, const ulonglong& b) { ulonglong c(a); return c|=b; } inline ulonglong operator^(const ulonglong& a, const ulonglong& b) { ulonglong c(a); return c^=b; } inline std::ostream& operator<<(std::ostream& out, const ulonglong& a) { return a.write(out); } inline std::istream& operator>>(std::istream& in, ulonglong& a) { return a.read(in); } #endif