]> git.saurik.com Git - wxWidgets.git/commitdiff
added test mode to wxLongLongWx which allowed to find the bug in operator*=()
authorVadim Zeitlin <vadim@wxwidgets.org>
Fri, 7 Jan 2000 20:35:34 +0000 (20:35 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Fri, 7 Jan 2000 20:35:34 +0000 (20:35 +0000)
which was breaking wxDateTime - now seems to work

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@5297 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

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

index b2b617a8046c3d3325cf166f4e1862a72b300ba8..d2f1ed26dead8c329f503c346acaef1223345b15 100644 (file)
 
 #include <limits.h>     // for LONG_MAX
 
-// #define wxUSE_LONGLONG_WX 1 // for testing (VZ)
+// define this to compile wxLongLongWx in "test" mode: the results of all
+// calculations will be compared with the real results taken from
+// wxLongLongNative
+#define wxLONGLONG_TEST_MODE
+
+#ifdef wxLONGLONG_TEST_MODE
+    #define wxUSE_LONGLONG_WX 1
+    #define wxUSE_LONGLONG_NATIVE 1
+#endif // wxLONGLONG_TEST_MODE
 
 // ----------------------------------------------------------------------------
 // decide upon which class we will use
 // to disable automatic testing (useful for the test program which defines
 // both classes) but by default we only use one class
 #if (defined(wxUSE_LONGLONG_WX) && wxUSE_LONGLONG_WX) || !defined(wxLongLong_t)
-    #undef wxUSE_LONGLONG_NATIVE
-    #define wxUSE_LONGLONG_NATIVE 0
+    // don't use both classes unless wxUSE_LONGLONG_NATIVE was explicitly set:
+    // this is useful in test programs nad only there
+    #ifndef wxUSE_LONGLONG_NATIVE
+        #define wxUSE_LONGLONG_NATIVE 0
+    #endif
+
     class WXDLLEXPORT wxLongLongWx;
     typedef wxLongLongWx wxLongLong;
 #else
@@ -307,13 +319,32 @@ class WXDLLEXPORT wxLongLongWx
 public:
     // ctors
         // default ctor initializes to 0
-    wxLongLongWx() { m_lo = m_hi = 0; }
+    wxLongLongWx()
+    {
+        m_lo = m_hi = 0;
+
+#ifdef wxLONGLONG_TEST_MODE
+        m_ll = 0;
+
+        Check();
+#endif // wxLONGLONG_TEST_MODE
+    }
         // from long
-    wxLongLongWx(long l)
-        { m_lo = l; m_hi = (l < 0 ? -1l : 0l); }
+    wxLongLongWx(long l) { *this = l; }
         // from 2 longs
     wxLongLongWx(long hi, unsigned long lo)
-        { m_hi = hi; m_lo = lo; }
+    {
+        m_hi = hi;
+        m_lo = lo;
+
+#ifdef wxLONGLONG_TEST_MODE
+        m_ll = hi;
+        m_ll <<= 32;
+        m_ll |= lo;
+
+        Check();
+#endif // wxLONGLONG_TEST_MODE
+    }
 
     // default copy ctor is ok in both cases
 
@@ -322,7 +353,18 @@ public:
     // assignment operators
         // from long
     wxLongLongWx& operator=(long l)
-        { m_lo = l; m_hi = (l < 0 ? -1l : 0l); return *this; }
+    {
+        m_lo = l;
+        m_hi = (l < 0 ? -1l : 0l);
+
+#ifdef wxLONGLONG_TEST_MODE
+        m_ll = l;
+
+        Check();
+#endif // wxLONGLONG_TEST_MODE
+
+        return *this;
+    }
         // from double
     wxLongLongWx& Assign(double d);
         // can't have assignment operator from 2 longs
@@ -335,12 +377,25 @@ public:
 
         // get absolute value
     wxLongLongWx Abs() const { return wxLongLongWx(*this).Abs(); }
-    wxLongLongWx& Abs() { if ( m_hi < 0 ) m_hi = -m_hi; return *this; }
+    wxLongLongWx& Abs()
+    {
+        if ( m_hi < 0 )
+            m_hi = -m_hi;
+
+#ifdef wxLONGLONG_TEST_MODE
+        if ( m_ll < 0 )
+            m_ll = -m_ll;
+
+        Check();
+#endif // wxLONGLONG_TEST_MODE
+
+        return *this;
+    }
 
         // convert to long with range checking in the debug mode (only!)
     long ToLong() const
     {
-        wxASSERT_MSG( m_hi == 0l,
+        wxASSERT_MSG( (m_hi == 0l) || (m_hi == -1l),
                       _T("wxLongLong to long conversion loss of precision") );
 
         return (long)m_lo;
@@ -357,10 +412,11 @@ public:
     wxLongLongWx& operator++();
 
         // post increment operator
-    wxLongLongWx& operator++(int);
+    wxLongLongWx& operator++(int) { return ++(*this); }
 
         // negation operator
     wxLongLongWx operator-() const;
+    wxLongLongWx& Negate();
 
         // subraction
     wxLongLongWx operator-(const wxLongLongWx& ll) const;
@@ -370,7 +426,7 @@ public:
     wxLongLongWx& operator--();
 
         // post decrement operator
-    wxLongLongWx& operator--(int);
+    wxLongLongWx& operator--(int) { return --(*this); }
 
     // shifts
         // left shift
@@ -421,13 +477,22 @@ public:
     friend ostream& operator<<(ostream&, const wxLongLongWx&);
 #endif // wxUSE_STD_IOSTREAM
 
-    void *asArray(void) const;
+    void *asArray() const;
 
 private:
     // long is at least 32 bits, so represent our 64bit number as 2 longs
 
     long m_hi;                // signed bit is in the high part
     unsigned long m_lo;
+
+#ifdef wxLONGLONG_TEST_MODE
+    void Check()
+    {
+        wxASSERT( (m_ll >> 32) == m_hi && (unsigned long)m_ll == m_lo );
+    }
+
+    wxLongLong_t m_ll;
+#endif // wxLONGLONG_TEST_MODE
 };
 
 #endif // wxUSE_LONGLONG_WX
index e0fc63111af78f4ee4d93f7abe32553223ce720f..e3c75ec71d2de895f2eef872ffcd01c6988b943a 100644 (file)
 // what to test?
 
 //#define TEST_ARRAYS
-#define TEST_CMDLINE
+//#define TEST_CMDLINE
 //#define TEST_DIR
 //#define TEST_LOG
 //#define TEST_LONGLONG
 //#define TEST_MIME
 //#define TEST_STRINGS
 //#define TEST_THREADS
-//#define TEST_TIME
+#define TEST_TIME
 
 // ============================================================================
 // implementation
@@ -219,6 +219,19 @@ static void TestMimeEnum()
 #include <wx/longlong.h>
 #include <wx/timer.h>
 
+// make a 64 bit number from 4 16 bit ones
+#define MAKE_LL(x1, x2, x3, x4) wxLongLong((x1 << 16) | x2, (x3 << 16) | x3)
+
+// get a random 64 bit number
+#define RAND_LL()   MAKE_LL(rand(), rand(), rand(), rand())
+
+#if wxUSE_LONGLONG_NATIVE
+inline bool operator==(const wxLongLongWx& a, const wxLongLongNative& b)
+    { return a.GetHi() == b.GetHi() && a.GetLo() == b.GetLo(); }
+inline bool operator==(const wxLongLongNative& a, const wxLongLongWx& b)
+    { return a.GetHi() == b.GetHi() && a.GetLo() == b.GetLo(); }
+#endif // wxUSE_LONGLONG_NATIVE
+
 static void TestSpeed()
 {
     static const long max = 100000000;
@@ -263,14 +276,75 @@ static void TestSpeed()
     }
 }
 
-static void TestDivision()
+static void TestLongLongConversion()
 {
-    puts("*** Testing wxLongLong division ***\n");
+    puts("*** Testing wxLongLong conversions ***\n");
+
+    wxLongLong a;
+    size_t nTested = 0;
+    for ( size_t n = 0; n < 100000; n++ )
+    {
+        a = RAND_LL();
+
+#if wxUSE_LONGLONG_NATIVE
+        wxLongLongNative b(a.GetHi(), a.GetLo());
 
-    #define MAKE_LL(x1, x2, x3, x4) wxLongLong((x1 << 16) | x2, (x3 << 16) | x3)
+        wxASSERT_MSG( a == b, "conversions failure" );
+#else
+        puts("Can't do it without native long long type, test skipped.");
 
-    // seed pseudo random generator
-    srand((unsigned)time(NULL));
+        return;
+#endif // wxUSE_LONGLONG_NATIVE
+
+        if ( !(nTested % 1000) )
+        {
+            putchar('.');
+            fflush(stdout);
+        }
+
+        nTested++;
+    }
+
+    puts(" done!");
+}
+
+static void TestMultiplication()
+{
+    puts("*** Testing wxLongLong multiplication ***\n");
+
+    wxLongLong a, b;
+    size_t nTested = 0;
+    for ( size_t n = 0; n < 100000; n++ )
+    {
+        a = RAND_LL();
+        b = RAND_LL();
+
+#if wxUSE_LONGLONG_NATIVE
+        wxLongLongNative aa(a.GetHi(), a.GetLo());
+        wxLongLongNative bb(b.GetHi(), b.GetLo());
+
+        wxASSERT_MSG( a*b == aa*bb, "multiplication failure" );
+#else // !wxUSE_LONGLONG_NATIVE
+        puts("Can't do it without native long long type, test skipped.");
+
+        return;
+#endif // wxUSE_LONGLONG_NATIVE
+
+        if ( !(nTested % 1000) )
+        {
+            putchar('.');
+            fflush(stdout);
+        }
+
+        nTested++;
+    }
+
+    puts(" done!");
+}
+
+static void TestDivision()
+{
+    puts("*** Testing wxLongLong division ***\n");
 
     wxLongLong q, r;
     size_t nTested = 0;
@@ -285,8 +359,15 @@ static void TestDivision()
         q = ll / l;
         r = ll % l;
 
+#if wxUSE_LONGLONG_NATIVE
+        wxLongLongNative m(ll.GetHi(), ll.GetLo());
+
+        wxLongLongNative p = m / l, s = m % l;
+        wxASSERT_MSG( q == p && r == s, "division failure" );
+#else // !wxUSE_LONGLONG_NATIVE
         // verify the result
         wxASSERT_MSG( ll == q*l + r, "division failure" );
+#endif // wxUSE_LONGLONG_NATIVE
 
         if ( !(nTested % 1000) )
         {
@@ -298,10 +379,87 @@ static void TestDivision()
     }
 
     puts(" done!");
+}
 
-    #undef MAKE_LL
+static void TestAddition()
+{
+    puts("*** Testing wxLongLong addition ***\n");
+
+    wxLongLong a, b, c;
+    size_t nTested = 0;
+    for ( size_t n = 0; n < 100000; n++ )
+    {
+        a = RAND_LL();
+        b = RAND_LL();
+        c = a + b;
+
+#if wxUSE_LONGLONG_NATIVE
+        wxASSERT_MSG( c == wxLongLongNative(a.GetHi(), a.GetLo()) +
+                           wxLongLongNative(b.GetHi(), b.GetLo()),
+                      "addition failure" ); 
+#else // !wxUSE_LONGLONG_NATIVE
+        wxASSERT_MSG( c - b == a, "addition failure" );
+#endif // wxUSE_LONGLONG_NATIVE
+
+        if ( !(nTested % 1000) )
+        {
+            putchar('.');
+            fflush(stdout);
+        }
+
+        nTested++;
+    }
+
+    puts(" done!");
 }
 
+static void TestBitOperations()
+{
+    puts("*** Testing wxLongLong bit operation ***\n");
+
+    wxLongLong a, c;
+    size_t nTested = 0;
+    for ( size_t n = 0; n < 100000; n++ )
+    {
+        a = RAND_LL();
+
+#if wxUSE_LONGLONG_NATIVE
+        for ( size_t n = 0; n < 33; n++ )
+        {
+            wxLongLongNative b(a.GetHi(), a.GetLo());
+
+            b >>= n;
+            c = a >> n;
+
+            wxASSERT_MSG( b == c, "bit shift failure" );
+
+            b = wxLongLongNative(a.GetHi(), a.GetLo()) << n;
+            c = a << n;
+
+            wxASSERT_MSG( b == c, "bit shift failure" );
+        }
+
+#else // !wxUSE_LONGLONG_NATIVE
+        puts("Can't do it without native long long type, test skipped.");
+
+        return;
+#endif // wxUSE_LONGLONG_NATIVE
+
+        if ( !(nTested % 1000) )
+        {
+            putchar('.');
+            fflush(stdout);
+        }
+
+        nTested++;
+    }
+
+    puts(" done!");
+}
+
+#undef MAKE_LL
+#undef RAND_LL
+
 #endif // TEST_LONGLONG
 
 // ----------------------------------------------------------------------------
@@ -1703,10 +1861,21 @@ int main(int argc, char **argv)
 #endif // TEST_THREADS
 
 #ifdef TEST_LONGLONG
+    // seed pseudo random generator
+    srand((unsigned)time(NULL));
+
     if ( 0 )
+    {
         TestSpeed();
-    if ( 1 )
+    }
+    TestMultiplication();
+    if ( 0 )
+    {
         TestDivision();
+        TestAddition();
+        TestLongLongConversion();
+        TestBitOperations();
+    }
 #endif // TEST_LONGLONG
 
 #ifdef TEST_MIME
@@ -1714,7 +1883,7 @@ int main(int argc, char **argv)
 #endif // TEST_MIME
 
 #ifdef TEST_TIME
-    if ( 0 )
+    if ( 1 )
     {
         TestTimeSet();
         TestTimeStatic();
index 2dd291fb1ce67a838f43525da6a19ec73d9a8d43..6a0cc8e315a4c91eddd175f102fe634fb649dfa3 100644 (file)
@@ -41,7 +41,7 @@
 // misc
 // ----------------------------------------------------------------------------
 
-void *wxLongLongNative::asArray(void) const
+void *wxLongLongNative::asArray() const
 {
     static unsigned char temp[8];
 
@@ -89,110 +89,121 @@ ostream& operator<< (ostream& o, const wxLongLongNative& ll)
 // assignment
 wxLongLongWx& wxLongLongWx::Assign(double d)
 {
-    if ( fabs(d) <= LONG_MAX )
+    bool positive = d >= 0;
+    d = fabs(d);
+    if ( d <= LONG_MAX )
     {
-        m_hi = d < 0 ? 1 << (8*sizeof(long) - 1) : 0l;
+        m_hi = 0;
         m_lo = (long)d;
     }
     else
     {
-        wxFAIL_MSG(_T("TODO"));       
+#if 0
+        m_lo = (long)d;
+        d -= m_lo;
+        d /=  0x1000;
+        d /=  0x1000;
+        d /=  0x100;
+        m_hi = (long)d;
+#else
+        wxFAIL_MSG(_T("TODO"));
+#endif
     }
 
+    if ( !positive )
+        m_hi = -m_hi;
+
+#ifdef wxLONGLONG_TEST_MODE
+    m_ll = (wxLongLong_t)d;
+
+    Check();
+#endif // wxLONGLONG_TEST_MODE
+
     return *this;
 }
 
 wxLongLongWx wxLongLongWx::operator<<(int shift) const
 {
-    if (shift == 0)
-        return *this;
+    wxLongLongWx ll(*this);
+    ll <<= shift;
 
-    if (shift < 32)
-        return wxLongLongWx((m_hi << shift) | (m_lo >> (32 - shift)),
-                             m_lo << shift);
-    else
-        return wxLongLongWx(m_lo << (shift - 32),
-                            0);
+    return ll;
 }
 
 wxLongLongWx& wxLongLongWx::operator<<=(int shift)
 {
-    if (shift == 0)
-        return *this;
-
-    if (shift < 32)
+    if (shift != 0)
     {
-        m_hi <<= shift;
-        m_hi |= m_lo >> (32 - shift);
-        m_lo <<= shift;
-    }
-    else
-    {
-        m_hi = m_lo << (shift - 32);
-        m_lo = 0;
+        if (shift < 32)
+        {
+            m_hi <<= shift;
+            m_hi |= m_lo >> (32 - shift);
+            m_lo <<= shift;
+        }
+        else
+        {
+            m_hi = m_lo << (shift - 32);
+            m_lo = 0;
+        }
     }
 
+#ifdef wxLONGLONG_TEST_MODE
+    m_ll <<= shift;
+
+    Check();
+#endif // wxLONGLONG_TEST_MODE
+
     return *this;
 }
 
 wxLongLongWx wxLongLongWx::operator>>(int shift) const
 {
-    if (shift == 0)
-        return *this;
+    wxLongLongWx ll(*this);
+    ll >>= shift;
 
-    if (shift < 32)
-        return wxLongLongWx(m_hi >> shift,
-                          (m_lo >> shift) | (m_hi << (32 - shift)));
-    else
-        return wxLongLongWx((m_hi < 0 ? -1l : 0),
-                          m_hi >> (shift - 32));
+    return ll;
 }
 
 wxLongLongWx& wxLongLongWx::operator>>=(int shift)
 {
-    if (shift == 0)
-        return *this;
-
-    if (shift < 32)
-    {
-        m_lo >>= shift;
-        m_lo |= m_hi << (32 - shift);
-        m_hi >>= shift;
-    }
-    else
+    if (shift != 0)
     {
-        m_lo = m_hi >> (shift - 32);
-        m_hi = (m_hi < 0 ? -1L : 0);
+        if (shift < 32)
+        {
+            m_lo >>= shift;
+            m_lo |= m_hi << (32 - shift);
+            m_hi >>= shift;
+        }
+        else
+        {
+            m_lo = m_hi >> (shift - 32);
+            m_hi = (m_hi < 0 ? -1L : 0);
+        }
     }
 
+#ifdef wxLONGLONG_TEST_MODE
+    m_ll >>= shift;
+
+    Check();
+#endif // wxLONGLONG_TEST_MODE
+
     return *this;
 }
 
 wxLongLongWx wxLongLongWx::operator+(const wxLongLongWx& ll) const
 {
-    wxLongLongWx temp;
+    wxLongLongWx res(*this);
+    res += ll;
 
-    temp.m_lo = m_lo + ll.m_lo;
-    temp.m_hi = m_hi + ll.m_hi;
-    if ((temp.m_lo < m_lo) || (temp.m_lo < ll.m_lo))
-        temp.m_hi++;
-
-    return temp;
+    return res;
 }
 
 wxLongLongWx wxLongLongWx::operator+(long l) const
 {
-    wxLongLongWx temp;
-
-    temp.m_lo = m_lo + l;
+    wxLongLongWx res(*this);
+    res += l;
 
-    if (l < 0)
-        temp.m_hi += -1l;
-
-    if ((temp.m_lo < m_lo) || (temp.m_lo < (unsigned long)l))
-        temp.m_hi++;
-
-    return temp;
+    return res;
 }
 
 wxLongLongWx& wxLongLongWx::operator+=(const wxLongLongWx& ll)
@@ -205,6 +216,12 @@ wxLongLongWx& wxLongLongWx::operator+=(const wxLongLongWx& ll)
     if ((m_lo < previous) || (m_lo < ll.m_lo))
         m_hi++;
 
+#ifdef wxLONGLONG_TEST_MODE
+    m_ll += ll.m_ll;
+
+    Check();
+#endif // wxLONGLONG_TEST_MODE
+
     return *this;
 }
 
@@ -219,6 +236,12 @@ wxLongLongWx& wxLongLongWx::operator+=(long l)
     if ((m_lo < previous) || (m_lo < (unsigned long)l))
         m_hi++;
 
+#ifdef wxLONGLONG_TEST_MODE
+    m_ll += l;
+
+    Check();
+#endif // wxLONGLONG_TEST_MODE
+
     return *this;
 }
 
@@ -229,15 +252,11 @@ wxLongLongWx& wxLongLongWx::operator++()
     if (m_lo == 0)
         m_hi++;
 
-    return *this;
-}
+#ifdef wxLONGLONG_TEST_MODE
+    m_ll++;
 
-// post increment
-wxLongLongWx& wxLongLongWx::operator++(int)
-{
-    m_lo++;
-    if (m_lo == 0)
-        m_hi++;
+    Check();
+#endif // wxLONGLONG_TEST_MODE
 
     return *this;
 }
@@ -245,28 +264,38 @@ wxLongLongWx& wxLongLongWx::operator++(int)
 // negation
 wxLongLongWx wxLongLongWx::operator-() const
 {
-    wxLongLongWx temp(~m_hi, ~m_lo);
+    wxLongLongWx res(*this);
+    res.Negate();
+
+    return res;
+}
+
+wxLongLongWx& wxLongLongWx::Negate()
+{
+    m_hi = ~m_hi;
+    m_lo = ~m_lo;
+
+    m_lo++;
+    if ( m_lo == 0 )
+        m_hi++;
 
-    temp.m_lo++;
-    if (temp.m_lo == 0)
-        temp.m_hi++;
+#ifdef wxLONGLONG_TEST_MODE
+    m_ll = -m_ll;
 
-    return temp;
+    Check();
+#endif // wxLONGLONG_TEST_MODE
+
+    return *this;
 }
 
 // subtraction
 
 wxLongLongWx wxLongLongWx::operator-(const wxLongLongWx& ll) const
 {
-    wxLongLongWx temp;
-
-    temp.m_lo = m_lo - ll.m_lo;
-    temp.m_hi = m_hi - ll.m_hi;
+    wxLongLongWx res(*this);
+    res -= ll;
 
-    if (m_lo < ll.m_lo)
-        temp.m_hi--;
-
-    return temp;
+    return res;
 }
 
 wxLongLongWx& wxLongLongWx::operator-=(const wxLongLongWx& ll)
@@ -279,6 +308,12 @@ wxLongLongWx& wxLongLongWx::operator-=(const wxLongLongWx& ll)
     if (previous < ll.m_lo)
         m_hi--;
 
+#ifdef wxLONGLONG_TEST_MODE
+    m_ll -= ll.m_ll;
+
+    Check();
+#endif // wxLONGLONG_TEST_MODE
+
     return *this;
 }
 
@@ -289,15 +324,11 @@ wxLongLongWx& wxLongLongWx::operator--()
     if (m_lo == 0xFFFFFFFF)
         m_hi--;
 
-    return *this;
-}
+#ifdef wxLONGLONG_TEST_MODE
+    m_ll--;
 
-// post decrement
-wxLongLongWx& wxLongLongWx::operator--(int)
-{
-    m_lo--;
-    if (m_lo == 0xFFFFFFFF)
-        m_hi--;
+    Check();
+#endif // wxLONGLONG_TEST_MODE
 
     return *this;
 }
@@ -346,6 +377,12 @@ wxLongLongWx& wxLongLongWx::operator&=(const wxLongLongWx& ll)
     m_lo &= ll.m_lo;
     m_hi &= ll.m_hi;
 
+#ifdef wxLONGLONG_TEST_MODE
+    m_ll &= ll.m_ll;
+
+    Check();
+#endif // wxLONGLONG_TEST_MODE
+
     return *this;
 }
 
@@ -354,6 +391,12 @@ wxLongLongWx& wxLongLongWx::operator|=(const wxLongLongWx& ll)
     m_lo |= ll.m_lo;
     m_hi |= ll.m_hi;
 
+#ifdef wxLONGLONG_TEST_MODE
+    m_ll |= ll.m_ll;
+
+    Check();
+#endif // wxLONGLONG_TEST_MODE
+
     return *this;
 }
 
@@ -362,6 +405,12 @@ wxLongLongWx& wxLongLongWx::operator^=(const wxLongLongWx& ll)
     m_lo ^= ll.m_lo;
     m_hi ^= ll.m_hi;
 
+#ifdef wxLONGLONG_TEST_MODE
+    m_ll ^= ll.m_ll;
+
+    Check();
+#endif // wxLONGLONG_TEST_MODE
+
     return *this;
 }
 
@@ -374,38 +423,41 @@ wxLongLongWx wxLongLongWx::operator~() const
 
 wxLongLongWx wxLongLongWx::operator*(const wxLongLongWx& ll) const
 {
-    wxLongLongWx t(m_hi, m_lo);
-    wxLongLongWx q(ll.m_hi, ll.m_lo);
-    wxLongLongWx p;
-    int counter = 0;
+    wxLongLongWx res(*this);
+    res *= ll;
 
-    do
-    {
-        if ((q.m_lo & 1) != 0)
-              p += t;
-        q >>= 1;
-        t <<= 1;
-        counter++;
-      }
-      while ((counter < 64) && ((q.m_hi != 0) || (q.m_lo != 0)));
-    return p;
+    return res;
 }
 
 wxLongLongWx& wxLongLongWx::operator*=(const wxLongLongWx& ll)
 {
     wxLongLongWx t(m_hi, m_lo);
     wxLongLongWx q(ll.m_hi, ll.m_lo);
-    int counter = 0;
 
+    m_hi = m_lo = 0;
+
+#ifdef wxLONGLONG_TEST_MODE
+    wxLongLong_t llOld = m_ll;
+    m_ll = 0;
+#endif // wxLONGLONG_TEST_MODE
+
+    int counter = 0;
     do
     {
         if ((q.m_lo & 1) != 0)
-              *this += t;
+            *this += t;
         q >>= 1;
         t <<= 1;
         counter++;
-      }
-      while ((counter < 64) && ((q.m_hi != 0) || (q.m_lo != 0)));
+    }
+    while ((counter < 64) && ((q.m_hi != 0) || (q.m_lo != 0)));
+
+#ifdef wxLONGLONG_TEST_MODE
+    m_ll = llOld * ll.m_ll;
+
+    Check();
+#endif // wxLONGLONG_TEST_MODE
+
     return *this;
 }
 
@@ -443,21 +495,6 @@ void wxLongLongWx::Divide(const wxLongLongWx& divisorIn,
     quotient = 0l;
     remainder = 0l;
 
-    // check for some particular cases
-    if ( divisor > dividend )
-    {
-        remainder = dividend;
-
-        return;
-    }
-
-    if ( divisor == dividend )
-    {
-        quotient = 1l;
-
-        return;
-    }
-
     // always do unsigned division and adjust the signs later: in C integer
     // division, the sign of the remainder is the same as the sign of the
     // dividend, while the sign of the quotient is the product of the signs of
@@ -479,47 +516,59 @@ void wxLongLongWx::Divide(const wxLongLongWx& divisorIn,
         divisor = -divisor;
     }
 
-    // here: dividend > divisor and both are positibe: do unsigned division
-    size_t nBits = 64u;
-    wxLongLongWx d;
-
-    #define IS_MSB_SET(ll)  ((ll.m_hi) & (1 << (8*sizeof(long) - 1)))
-
-    while ( remainder < divisor )
+    // check for some particular cases
+    if ( divisor > dividend )
     {
-        remainder <<= 1;
-        if ( IS_MSB_SET(dividend) )
-        {
-            remainder |= 1;
-        }
-
-        d = dividend;
-        dividend <<= 1;
-
-        nBits--;
+        remainder = dividend;
+    }
+    else if ( divisor == dividend )
+    {
+        quotient = 1l;
     }
+    else
+    {
+        // here: dividend > divisor and both are positibe: do unsigned division
+        size_t nBits = 64u;
+        wxLongLongWx d;
 
-    // undo the last loop iteration
-    dividend = d;
-    remainder >>= 1;
-    nBits++;
+        #define IS_MSB_SET(ll)  ((ll.m_hi) & (1 << (8*sizeof(long) - 1)))
 
-    for ( size_t i = 0; i < nBits; i++ )
-    {
-        remainder <<= 1;
-        if ( IS_MSB_SET(dividend) )
+        while ( remainder < divisor )
         {
-            remainder |= 1;
+            remainder <<= 1;
+            if ( IS_MSB_SET(dividend) )
+            {
+                remainder |= 1;
+            }
+
+            d = dividend;
+            dividend <<= 1;
+
+            nBits--;
         }
 
-        wxLongLongWx t = remainder - divisor;
-        dividend <<= 1;
-        quotient <<= 1;
-        if ( !IS_MSB_SET(t) )
-        {
-            quotient |= 1;
+        // undo the last loop iteration
+        dividend = d;
+        remainder >>= 1;
+        nBits++;
 
-            remainder = t;
+        for ( size_t i = 0; i < nBits; i++ )
+        {
+            remainder <<= 1;
+            if ( IS_MSB_SET(dividend) )
+            {
+                remainder |= 1;
+            }
+
+            wxLongLongWx t = remainder - divisor;
+            dividend <<= 1;
+            quotient <<= 1;
+            if ( !IS_MSB_SET(t) )
+            {
+                quotient |= 1;
+
+                remainder = t;
+            }
         }
     }