]> git.saurik.com Git - wxWidgets.git/commitdiff
tried to implement division of wxLongLongs - doesn't work at all, will finish tonight
authorVadim Zeitlin <vadim@wxwidgets.org>
Thu, 23 Dec 1999 20:15:40 +0000 (20:15 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Thu, 23 Dec 1999 20:15:40 +0000 (20:15 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@5090 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/longlong.h
samples/console/console.cpp
src/common/longlong.cpp

index a3e8281d27a547c96c29b83c457f51ceea8b46a0..454d7e5b8d0b9ecd4a1fdc0994b4fcde41fe1ac3 100644 (file)
@@ -25,6 +25,8 @@
 
 #include <limits.h>     // 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
index 4390f2acb8d4567688cbd81ba3eb660bbd610c70..771db68871bb711c51874fd9307e614b05cedd41 100644 (file)
 //#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++;
     }
index 5493e0bfca3fb970bf4fd3f70fd592b51a67ea5f..bca0d2d1fede0ef6bc56bcbf6b086ec1a8d91413 100644 (file)
@@ -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
 {