From 2ea24d9f47002ce2965b6c782849f2f9b776c3de Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 23 Dec 1999 20:15:40 +0000 Subject: [PATCH 1/1] tried to implement division of wxLongLongs - doesn't work at all, will finish tonight git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@5090 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/longlong.h | 32 ++++++++-- samples/console/console.cpp | 18 ++++-- src/common/longlong.cpp | 124 +++++++++++++++++++++++------------- 3 files changed, 119 insertions(+), 55 deletions(-) diff --git a/include/wx/longlong.h b/include/wx/longlong.h index a3e8281d27..454d7e5b8d 100644 --- a/include/wx/longlong.h +++ b/include/wx/longlong.h @@ -25,6 +25,8 @@ #include // for LONG_MAX +#define wxUSE_LONGLONG_WX 1 + // ---------------------------------------------------------------------------- // decide upon which class we will use // ---------------------------------------------------------------------------- @@ -68,7 +70,7 @@ // the user may predefine wxUSE_LONGLONG_NATIVE and/or wxUSE_LONGLONG_NATIVE // to disable automatic testing (useful for the test program which defines // both classes) but by default we only use one class -#ifndef wxLongLong_t +#if (defined(wxUSE_LONGLONG_WX) && wxUSE_LONGLONG_WX) || !defined(wxLongLong_t) #undef wxUSE_LONGLONG_NATIVE #define wxUSE_LONGLONG_NATIVE 0 class WXDLLEXPORT wxLongLongWx; @@ -140,6 +142,7 @@ public: { return (unsigned long)m_ll; } // get absolute value + wxLongLongNative Abs() const { return wxLongLongNative(*this).Abs(); } wxLongLongNative& Abs() { if ( m_ll < 0 ) m_ll = -m_ll; return *this; } // convert to native long long @@ -329,6 +332,7 @@ public: unsigned long GetLo() const { return m_lo; } // get absolute value + wxLongLongWx Abs() const { return wxLongLongWx(*this).Abs(); } wxLongLongWx& Abs() { if ( m_hi < 0 ) m_hi = -m_hi; return *this; } // convert to long with range checking in the debug mode (only!) @@ -385,12 +389,16 @@ public: wxLongLongWx operator~() const; // comparison - bool operator==(const wxLongLongWx& ll) const; - bool operator!=(const wxLongLongWx& ll) const; + bool operator==(const wxLongLongWx& ll) const + { return m_lo == ll.m_lo && m_hi == ll.m_hi; } + bool operator!=(const wxLongLongWx& ll) const + { return !(*this == ll); } bool operator<(const wxLongLongWx& ll) const; bool operator>(const wxLongLongWx& ll) const; - bool operator<=(const wxLongLongWx& ll) const; - bool operator>=(const wxLongLongWx& ll) const; + bool operator<=(const wxLongLongWx& ll) const + { return *this < ll || *this == ll; } + bool operator>=(const wxLongLongWx& ll) const + { return *this > ll || *this == ll; } // multiplication wxLongLongWx operator*(const wxLongLongWx& ll) const; @@ -422,4 +430,18 @@ private: #endif // wxUSE_LONGLONG_WX +// ---------------------------------------------------------------------------- +// binary operators +// ---------------------------------------------------------------------------- + +inline bool WXDLLEXPORT operator<(long l, const wxLongLong& ll) { return ll > l; } +inline bool WXDLLEXPORT operator>(long l, const wxLongLong& ll) { return ll > l; } +inline bool WXDLLEXPORT operator<=(long l, const wxLongLong& ll) { return ll > l; } +inline bool WXDLLEXPORT operator>=(long l, const wxLongLong& ll) { return ll > l; } +inline bool WXDLLEXPORT operator==(long l, const wxLongLong& ll) { return ll > l; } +inline bool WXDLLEXPORT operator!=(long l, const wxLongLong& ll) { return ll > l; } + +inline wxLongLong WXDLLEXPORT operator+(long l, const wxLongLong& ll) { return ll + l; } +inline wxLongLong WXDLLEXPORT operator-(long l, const wxLongLong& ll) { return ll - l; } + #endif // _WX_LONGLONG_H diff --git a/samples/console/console.cpp b/samples/console/console.cpp index 4390f2acb8..771db68871 100644 --- a/samples/console/console.cpp +++ b/samples/console/console.cpp @@ -32,11 +32,11 @@ //#define TEST_ARRAYS //#define TEST_DIR //#define TEST_LOG +#define TEST_LONGLONG //#define TEST_MIME //#define TEST_STRINGS //#define TEST_THREADS -#define TEST_TIME -//#define TEST_LONGLONG +//#define TEST_TIME // ============================================================================ // implementation @@ -195,17 +195,19 @@ static void TestSpeed() printf("Summing longs took %ld milliseconds.\n", sw.Time()); } +#if wxUSE_LONGLONG_NATIVE { wxStopWatch sw; - __int64 l = 0; + wxLongLong_t l = 0; for ( n = 0; n < max; n++ ) { l += n; } - printf("Summing __int64s took %ld milliseconds.\n", sw.Time()); + printf("Summing wxLongLong_t took %ld milliseconds.\n", sw.Time()); } +#endif // wxUSE_LONGLONG_NATIVE { wxStopWatch sw; @@ -227,6 +229,7 @@ static void TestDivision() // seed pseudo random generator //srand((unsigned)time(NULL)); + wxLongLong q, r; size_t nTested = 0; for ( size_t n = 0; n < 10000; n++ ) { @@ -234,7 +237,12 @@ static void TestDivision() // multiplication will not overflow) wxLongLong ll = MAKE_LL((rand() >> 12), rand(), rand(), rand()); - wxASSERT( (ll * 1000l)/1000l == ll ); + // get a random long (not wxLongLong for now) to divide it with + long l = rand(); + q = ll / l; + r = ll % l; + + wxASSERT_MSG( ll == q*l + r, "division failure" ); nTested++; } diff --git a/src/common/longlong.cpp b/src/common/longlong.cpp index 5493e0bfca..bca0d2d1fe 100644 --- a/src/common/longlong.cpp +++ b/src/common/longlong.cpp @@ -286,54 +286,22 @@ wxLongLongWx& wxLongLongWx::operator--(int) bool wxLongLongWx::operator<(const wxLongLongWx& ll) const { - if (m_lo < ll.m_lo) - return 1; - if (m_lo > ll.m_lo) - return 0; - if (m_hi < ll.m_hi) - return 1; - if (m_hi > ll.m_hi) - return 0; - return 0; + if ( m_hi < ll.m_hi ) + return TRUE; + else if ( m_hi == ll.m_hi ) + return m_lo < ll.m_lo; + else + return FALSE; } bool wxLongLongWx::operator>(const wxLongLongWx& ll) const { - if (m_lo < ll.m_lo) - return 0; - if (m_lo > ll.m_lo) - return 1; - if (m_hi < ll.m_hi) - return 0; - if (m_hi > ll.m_hi) - return 1; - return 0; -} - -bool wxLongLongWx::operator<=(const wxLongLongWx& ll) const -{ - if (m_lo < ll.m_lo) - return 1; - if (m_lo > ll.m_lo) - return 0; - if (m_hi < ll.m_hi) - return 1; - if (m_hi > ll.m_hi) - return 0; - return 1; -} - -bool wxLongLongWx::operator>=(const wxLongLongWx& ll) const -{ - if (m_lo < ll.m_lo) - return 0; - if (m_lo > ll.m_lo) - return 1; - if (m_hi < ll.m_hi) - return 0; - if (m_hi > ll.m_hi) - return 1; - return 1; + if ( m_hi > ll.m_hi ) + return TRUE; + else if ( m_hi == ll.m_hi ) + return m_lo > ll.m_lo; + else + return FALSE; } // bitwise operators @@ -435,9 +403,75 @@ void wxLongLongWx::Divide(const wxLongLongWx& divisor, dummy += 0; } - wxFAIL_MSG("not implemented"); + // VZ: I'm writing this in a hurry and it's surely not the fastest way to + // do this - any improvements are more than welcome + + // the algorithm: first find N such that 2^N * divisor is less than us, + // then substract divisor from *this - 2^N * divisor as many times as + // possible + + wxLongLongWx prev = divisor; + remainder = *this; + + quotient = 1l; + + for ( wxLongLongWx tmp = divisor; tmp < remainder; ) + { + prev = tmp; + + tmp <<= 1; + + if ( tmp < 0 ) + { + // shifted too far + break; + } + + quotient <<= 1; + } + + while ( remainder >= prev ) + { + remainder -= divisor; + quotient++; + } + + // remainder should be in this range at the end + wxASSERT_MSG( (0l <= remainder) && (remainder < divisor.Abs()), + _T("logic error in wxLongLong division") ); +} + +wxLongLongWx wxLongLongWx::operator/(const wxLongLongWx& ll) const +{ + wxLongLongWx quotient, remainder; + + Divide(ll, quotient, remainder); + + return quotient; +} + +wxLongLongWx& wxLongLongWx::operator/=(const wxLongLongWx& ll) +{ + wxLongLongWx quotient, remainder; + + Divide(ll, quotient, remainder); + + return *this = quotient; } +wxLongLongWx wxLongLongWx::operator%(const wxLongLongWx& ll) const +{ + wxLongLongWx quotient, remainder; + + Divide(ll, quotient, remainder); + + return remainder; +} + +// ---------------------------------------------------------------------------- +// misc +// ---------------------------------------------------------------------------- + // temporary - just for testing void *wxLongLongWx::asArray(void) const { -- 2.45.2