home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / src / common / longlong.cpp < prev    next >
C/C++ Source or Header  |  2001-12-07  |  24KB  |  1,142 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        wx/longlong.cpp
  3. // Purpose:     implementation of wxLongLongNative
  4. // Author:      Jeffrey C. Ollie <jeff@ollie.clive.ia.us>, Vadim Zeitlin
  5. // Remarks:     this class is not public in wxWindows 2.0! It is intentionally
  6. //              not documented and is for private use only.
  7. // Modified by:
  8. // Created:     10.02.99
  9. // RCS-ID:      $Id: longlong.cpp,v 1.24 2001/12/07 22:40:17 VS Exp $
  10. // Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
  11. // Licence:     wxWindows license
  12. /////////////////////////////////////////////////////////////////////////////
  13.  
  14. // ============================================================================
  15. // headers
  16. // ============================================================================
  17.  
  18. #ifdef __GNUG__
  19.     #pragma implementation "longlong.h"
  20. #endif
  21.  
  22. #include "wx/wxprec.h"
  23.  
  24. #ifdef __BORLANDC__
  25.     #pragma hdrstop
  26. #endif
  27.  
  28. #if wxUSE_LONGLONG
  29. #include "wx/longlong.h"
  30.  
  31. #if defined(__MWERKS__) && defined(__WXMSW__)
  32. #include <string.h>     // for memset()
  33. #else
  34. #include <memory.h>     // for memset()
  35. #endif
  36.  
  37. #include <math.h>       // for fabs()
  38.  
  39. // ============================================================================
  40. // implementation
  41. // ============================================================================
  42.  
  43. #if wxUSE_LONGLONG_NATIVE
  44.  
  45. // ----------------------------------------------------------------------------
  46. // misc
  47. // ----------------------------------------------------------------------------
  48.  
  49. void *wxLongLongNative::asArray() const
  50. {
  51.     static unsigned char temp[8];
  52.  
  53.     temp[0] = (m_ll >> 56) & 0xFF;
  54.     temp[1] = (m_ll >> 48) & 0xFF;
  55.     temp[2] = (m_ll >> 40) & 0xFF;
  56.     temp[3] = (m_ll >> 32) & 0xFF;
  57.     temp[4] = (m_ll >> 24) & 0xFF;
  58.     temp[5] = (m_ll >> 16) & 0xFF;
  59.     temp[6] = (m_ll >> 8)  & 0xFF;
  60.     temp[7] = (m_ll >> 0)  & 0xFF;
  61.  
  62.     return temp;
  63. }
  64.  
  65. void *wxULongLongNative::asArray() const
  66. {
  67.     static unsigned char temp[8];
  68.  
  69.     temp[0] = (m_ll >> 56) & 0xFF;
  70.     temp[1] = (m_ll >> 48) & 0xFF;
  71.     temp[2] = (m_ll >> 40) & 0xFF;
  72.     temp[3] = (m_ll >> 32) & 0xFF;
  73.     temp[4] = (m_ll >> 24) & 0xFF;
  74.     temp[5] = (m_ll >> 16) & 0xFF;
  75.     temp[6] = (m_ll >> 8)  & 0xFF;
  76.     temp[7] = (m_ll >> 0)  & 0xFF;
  77.  
  78.     return temp;
  79. }
  80.  
  81. #endif // wxUSE_LONGLONG_NATIVE
  82.  
  83. // ============================================================================
  84. // wxLongLongWx: emulation of 'long long' using 2 longs
  85. // ============================================================================
  86.  
  87. #if wxUSE_LONGLONG_WX
  88.  
  89. // assignment
  90. wxLongLongWx& wxLongLongWx::Assign(double d)
  91. {
  92.     bool positive = d >= 0;
  93.     d = fabs(d);
  94.     if ( d <= ULONG_MAX )
  95.     {
  96.         m_hi = 0;
  97.         m_lo = (long)d;
  98.     }
  99.     else
  100.     {
  101.         m_hi = (unsigned long)(d / (1.0 + (double)ULONG_MAX));
  102.         m_lo = (unsigned long)(d - ((double)m_hi * (1.0 + (double)ULONG_MAX)));
  103.     }
  104.  
  105. #ifdef wxLONGLONG_TEST_MODE
  106.     m_ll = (wxLongLong_t)d;
  107.  
  108.     Check();
  109. #endif // wxLONGLONG_TEST_MODE
  110.  
  111.     if ( !positive )
  112.         Negate();
  113.  
  114.     return *this;
  115. }
  116.  
  117. wxLongLongWx wxLongLongWx::operator<<(int shift) const
  118. {
  119.     wxLongLongWx ll(*this);
  120.     ll <<= shift;
  121.  
  122.     return ll;
  123. }
  124.  
  125. wxULongLongWx wxULongLongWx::operator<<(int shift) const
  126. {
  127.     wxULongLongWx ll(*this);
  128.     ll <<= shift;
  129.  
  130.     return ll;
  131. }
  132.  
  133. wxLongLongWx& wxLongLongWx::operator<<=(int shift)
  134. {
  135.     if (shift != 0)
  136.     {
  137.         if (shift < 32)
  138.         {
  139.             m_hi <<= shift;
  140.             m_hi |= m_lo >> (32 - shift);
  141.             m_lo <<= shift;
  142.         }
  143.         else
  144.         {
  145.             m_hi = m_lo << (shift - 32);
  146.             m_lo = 0;
  147.         }
  148.     }
  149.  
  150. #ifdef wxLONGLONG_TEST_MODE
  151.     m_ll <<= shift;
  152.  
  153.     Check();
  154. #endif // wxLONGLONG_TEST_MODE
  155.  
  156.     return *this;
  157. }
  158.  
  159. wxULongLongWx& wxULongLongWx::operator<<=(int shift)
  160. {
  161.     if (shift != 0)
  162.     {
  163.         if (shift < 32)
  164.         {
  165.             m_hi <<= shift;
  166.             m_hi |= m_lo >> (32 - shift);
  167.             m_lo <<= shift;
  168.         }
  169.         else
  170.         {
  171.             m_hi = m_lo << (shift - 32);
  172.             m_lo = 0;
  173.         }
  174.     }
  175.  
  176. #ifdef wxLONGLONG_TEST_MODE
  177.     m_ll <<= shift;
  178.  
  179.     Check();
  180. #endif // wxLONGLONG_TEST_MODE
  181.  
  182.     return *this;
  183. }
  184.  
  185. wxLongLongWx wxLongLongWx::operator>>(int shift) const
  186. {
  187.     wxLongLongWx ll(*this);
  188.     ll >>= shift;
  189.  
  190.     return ll;
  191. }
  192.  
  193. wxULongLongWx wxULongLongWx::operator>>(int shift) const
  194. {
  195.     wxULongLongWx ll(*this);
  196.     ll >>= shift;
  197.  
  198.     return ll;
  199. }
  200.  
  201. wxLongLongWx& wxLongLongWx::operator>>=(int shift)
  202. {
  203.     if (shift != 0)
  204.     {
  205.         if (shift < 32)
  206.         {
  207.             m_lo >>= shift;
  208.             m_lo |= m_hi << (32 - shift);
  209.             m_hi >>= shift;
  210.         }
  211.         else
  212.         {
  213.             m_lo = m_hi >> (shift - 32);
  214.             m_hi = (m_hi < 0 ? -1L : 0);
  215.         }
  216.     }
  217.  
  218. #ifdef wxLONGLONG_TEST_MODE
  219.     m_ll >>= shift;
  220.  
  221.     Check();
  222. #endif // wxLONGLONG_TEST_MODE
  223.  
  224.     return *this;
  225. }
  226.  
  227. wxULongLongWx& wxULongLongWx::operator>>=(int shift)
  228. {
  229.     if (shift != 0)
  230.     {
  231.         if (shift < 32)
  232.         {
  233.             m_lo >>= shift;
  234.             m_lo |= m_hi << (32 - shift);
  235.             m_hi >>= shift;
  236.         }
  237.         else
  238.         {
  239.             m_lo = m_hi >> (shift - 32);
  240.             m_hi = 0;
  241.         }
  242.     }
  243.  
  244. #ifdef wxLONGLONG_TEST_MODE
  245.     m_ll >>= shift;
  246.  
  247.     Check();
  248. #endif // wxLONGLONG_TEST_MODE
  249.  
  250.     return *this;
  251. }
  252.  
  253. wxLongLongWx wxLongLongWx::operator+(const wxLongLongWx& ll) const
  254. {
  255.     wxLongLongWx res(*this);
  256.     res += ll;
  257.  
  258.     return res;
  259. }
  260.  
  261. wxULongLongWx wxULongLongWx::operator+(const wxULongLongWx& ll) const
  262. {
  263.     wxULongLongWx res(*this);
  264.     res += ll;
  265.  
  266.     return res;
  267. }
  268.  
  269. wxLongLongWx wxLongLongWx::operator+(long l) const
  270. {
  271.     wxLongLongWx res(*this);
  272.     res += l;
  273.  
  274.     return res;
  275. }
  276.  
  277. wxULongLongWx wxULongLongWx::operator+(unsigned long l) const
  278. {
  279.     wxULongLongWx res(*this);
  280.     res += l;
  281.  
  282.     return res;
  283. }
  284.  
  285. wxLongLongWx& wxLongLongWx::operator+=(const wxLongLongWx& ll)
  286. {
  287.     unsigned long previous = m_lo;
  288.  
  289.     m_lo += ll.m_lo;
  290.     m_hi += ll.m_hi;
  291.  
  292.     if ((m_lo < previous) || (m_lo < ll.m_lo))
  293.         m_hi++;
  294.  
  295. #ifdef wxLONGLONG_TEST_MODE
  296.     m_ll += ll.m_ll;
  297.  
  298.     Check();
  299. #endif // wxLONGLONG_TEST_MODE
  300.  
  301.     return *this;
  302. }
  303.  
  304. wxULongLongWx& wxULongLongWx::operator+=(const wxULongLongWx& ll)
  305. {
  306.     unsigned long previous = m_lo;
  307.  
  308.     m_lo += ll.m_lo;
  309.     m_hi += ll.m_hi;
  310.  
  311.     if ((m_lo < previous) || (m_lo < ll.m_lo))
  312.         m_hi++;
  313.  
  314. #ifdef wxLONGLONG_TEST_MODE
  315.     m_ll += ll.m_ll;
  316.  
  317.     Check();
  318. #endif // wxLONGLONG_TEST_MODE
  319.  
  320.     return *this;
  321. }
  322.  
  323. wxLongLongWx& wxLongLongWx::operator+=(long l)
  324. {
  325.     unsigned long previous = m_lo;
  326.  
  327.     m_lo += l;
  328.     if (l < 0)
  329.         m_hi += -1l;
  330.  
  331.     if ((m_lo < previous) || (m_lo < (unsigned long)l))
  332.         m_hi++;
  333.  
  334. #ifdef wxLONGLONG_TEST_MODE
  335.     m_ll += l;
  336.  
  337.     Check();
  338. #endif // wxLONGLONG_TEST_MODE
  339.  
  340.     return *this;
  341. }
  342.  
  343. wxULongLongWx& wxULongLongWx::operator+=(unsigned long l)
  344. {
  345.     unsigned long previous = m_lo;
  346.  
  347.     m_lo += l;
  348.  
  349.     if ((m_lo < previous) || (m_lo < l))
  350.         m_hi++;
  351.  
  352. #ifdef wxLONGLONG_TEST_MODE
  353.     m_ll += l;
  354.  
  355.     Check();
  356. #endif // wxLONGLONG_TEST_MODE
  357.  
  358.     return *this;
  359. }
  360.  
  361. // pre increment
  362. wxLongLongWx& wxLongLongWx::operator++()
  363. {
  364.     m_lo++;
  365.     if (m_lo == 0)
  366.         m_hi++;
  367.  
  368. #ifdef wxLONGLONG_TEST_MODE
  369.     m_ll++;
  370.  
  371.     Check();
  372. #endif // wxLONGLONG_TEST_MODE
  373.  
  374.     return *this;
  375. }
  376.  
  377. wxULongLongWx& wxULongLongWx::operator++()
  378. {
  379.     m_lo++;
  380.     if (m_lo == 0)
  381.         m_hi++;
  382.  
  383. #ifdef wxLONGLONG_TEST_MODE
  384.     m_ll++;
  385.  
  386.     Check();
  387. #endif // wxLONGLONG_TEST_MODE
  388.  
  389.     return *this;
  390. }
  391.  
  392. // negation
  393. wxLongLongWx wxLongLongWx::operator-() const
  394. {
  395.     wxLongLongWx res(*this);
  396.     res.Negate();
  397.  
  398.     return res;
  399. }
  400.  
  401. wxLongLongWx& wxLongLongWx::Negate()
  402. {
  403.     m_hi = ~m_hi;
  404.     m_lo = ~m_lo;
  405.  
  406.     m_lo++;
  407.     if ( m_lo == 0 )
  408.         m_hi++;
  409.  
  410. #ifdef wxLONGLONG_TEST_MODE
  411.     m_ll = -m_ll;
  412.  
  413.     Check();
  414. #endif // wxLONGLONG_TEST_MODE
  415.  
  416.     return *this;
  417. }
  418.  
  419. // subtraction
  420.  
  421. wxLongLongWx wxLongLongWx::operator-(const wxLongLongWx& ll) const
  422. {
  423.     wxLongLongWx res(*this);
  424.     res -= ll;
  425.  
  426.     return res;
  427. }
  428.  
  429. wxULongLongWx wxULongLongWx::operator-(const wxULongLongWx& ll) const
  430. {
  431.     wxULongLongWx res(*this);
  432.     res -= ll;
  433.  
  434.     return res;
  435. }
  436.  
  437. wxLongLongWx& wxLongLongWx::operator-=(const wxLongLongWx& ll)
  438. {
  439.     unsigned long previous = m_lo;
  440.  
  441.     m_lo -= ll.m_lo;
  442.     m_hi -= ll.m_hi;
  443.  
  444.     if (previous < ll.m_lo)
  445.         m_hi--;
  446.  
  447. #ifdef wxLONGLONG_TEST_MODE
  448.     m_ll -= ll.m_ll;
  449.  
  450.     Check();
  451. #endif // wxLONGLONG_TEST_MODE
  452.  
  453.     return *this;
  454. }
  455.  
  456. wxULongLongWx& wxULongLongWx::operator-=(const wxULongLongWx& ll)
  457. {
  458.     unsigned long previous = m_lo;
  459.  
  460.     m_lo -= ll.m_lo;
  461.     m_hi -= ll.m_hi;
  462.  
  463.     if (previous < ll.m_lo)
  464.         m_hi--;
  465.  
  466. #ifdef wxLONGLONG_TEST_MODE
  467.     m_ll -= ll.m_ll;
  468.  
  469.     Check();
  470. #endif // wxLONGLONG_TEST_MODE
  471.  
  472.     return *this;
  473. }
  474.  
  475. // pre decrement
  476. wxLongLongWx& wxLongLongWx::operator--()
  477. {
  478.     m_lo--;
  479.     if (m_lo == 0xFFFFFFFF)
  480.         m_hi--;
  481.  
  482. #ifdef wxLONGLONG_TEST_MODE
  483.     m_ll--;
  484.  
  485.     Check();
  486. #endif // wxLONGLONG_TEST_MODE
  487.  
  488.     return *this;
  489. }
  490.  
  491. wxULongLongWx& wxULongLongWx::operator--()
  492. {
  493.     m_lo--;
  494.     if (m_lo == 0xFFFFFFFF)
  495.         m_hi--;
  496.  
  497. #ifdef wxLONGLONG_TEST_MODE
  498.     m_ll--;
  499.  
  500.     Check();
  501. #endif // wxLONGLONG_TEST_MODE
  502.  
  503.     return *this;
  504. }
  505.  
  506. // comparison operators
  507.  
  508. bool wxLongLongWx::operator<(const wxLongLongWx& ll) const
  509. {
  510.     if ( m_hi < ll.m_hi )
  511.         return TRUE;
  512.     else if ( m_hi == ll.m_hi )
  513.         return m_lo < ll.m_lo;
  514.     else
  515.         return FALSE;
  516. }
  517.  
  518. bool wxULongLongWx::operator<(const wxULongLongWx& ll) const
  519. {
  520.     if ( m_hi < ll.m_hi )
  521.         return TRUE;
  522.     else if ( m_hi == ll.m_hi )
  523.         return m_lo < ll.m_lo;
  524.     else
  525.         return FALSE;
  526. }
  527.  
  528. bool wxLongLongWx::operator>(const wxLongLongWx& ll) const
  529. {
  530.     if ( m_hi > ll.m_hi )
  531.         return TRUE;
  532.     else if ( m_hi == ll.m_hi )
  533.         return m_lo > ll.m_lo;
  534.     else
  535.         return FALSE;
  536. }
  537.  
  538. bool wxULongLongWx::operator>(const wxULongLongWx& ll) const
  539. {
  540.     if ( m_hi > ll.m_hi )
  541.         return TRUE;
  542.     else if ( m_hi == ll.m_hi )
  543.         return m_lo > ll.m_lo;
  544.     else
  545.         return FALSE;
  546. }
  547.  
  548. // bitwise operators
  549.  
  550. wxLongLongWx wxLongLongWx::operator&(const wxLongLongWx& ll) const
  551. {
  552.     return wxLongLongWx(m_hi & ll.m_hi, m_lo & ll.m_lo);
  553. }
  554.  
  555. wxULongLongWx wxULongLongWx::operator&(const wxULongLongWx& ll) const
  556. {
  557.     return wxULongLongWx(m_hi & ll.m_hi, m_lo & ll.m_lo);
  558. }
  559.  
  560. wxLongLongWx wxLongLongWx::operator|(const wxLongLongWx& ll) const
  561. {
  562.     return wxLongLongWx(m_hi | ll.m_hi, m_lo | ll.m_lo);
  563. }
  564.  
  565. wxULongLongWx wxULongLongWx::operator|(const wxULongLongWx& ll) const
  566. {
  567.     return wxULongLongWx(m_hi | ll.m_hi, m_lo | ll.m_lo);
  568. }
  569.  
  570. wxLongLongWx wxLongLongWx::operator^(const wxLongLongWx& ll) const
  571. {
  572.     return wxLongLongWx(m_hi ^ ll.m_hi, m_lo ^ ll.m_lo);
  573. }
  574.  
  575. wxULongLongWx wxULongLongWx::operator^(const wxULongLongWx& ll) const
  576. {
  577.     return wxULongLongWx(m_hi ^ ll.m_hi, m_lo ^ ll.m_lo);
  578. }
  579.  
  580. wxLongLongWx& wxLongLongWx::operator&=(const wxLongLongWx& ll)
  581. {
  582.     m_lo &= ll.m_lo;
  583.     m_hi &= ll.m_hi;
  584.  
  585. #ifdef wxLONGLONG_TEST_MODE
  586.     m_ll &= ll.m_ll;
  587.  
  588.     Check();
  589. #endif // wxLONGLONG_TEST_MODE
  590.  
  591.     return *this;
  592. }
  593.  
  594. wxULongLongWx& wxULongLongWx::operator&=(const wxULongLongWx& ll)
  595. {
  596.     m_lo &= ll.m_lo;
  597.     m_hi &= ll.m_hi;
  598.  
  599. #ifdef wxLONGLONG_TEST_MODE
  600.     m_ll &= ll.m_ll;
  601.  
  602.     Check();
  603. #endif // wxLONGLONG_TEST_MODE
  604.  
  605.     return *this;
  606. }
  607.  
  608. wxLongLongWx& wxLongLongWx::operator|=(const wxLongLongWx& ll)
  609. {
  610.     m_lo |= ll.m_lo;
  611.     m_hi |= ll.m_hi;
  612.  
  613. #ifdef wxLONGLONG_TEST_MODE
  614.     m_ll |= ll.m_ll;
  615.  
  616.     Check();
  617. #endif // wxLONGLONG_TEST_MODE
  618.  
  619.     return *this;
  620. }
  621.  
  622. wxULongLongWx& wxULongLongWx::operator|=(const wxULongLongWx& ll)
  623. {
  624.     m_lo |= ll.m_lo;
  625.     m_hi |= ll.m_hi;
  626.  
  627. #ifdef wxLONGLONG_TEST_MODE
  628.     m_ll |= ll.m_ll;
  629.  
  630.     Check();
  631. #endif // wxLONGLONG_TEST_MODE
  632.  
  633.     return *this;
  634. }
  635.  
  636. wxLongLongWx& wxLongLongWx::operator^=(const wxLongLongWx& ll)
  637. {
  638.     m_lo ^= ll.m_lo;
  639.     m_hi ^= ll.m_hi;
  640.  
  641. #ifdef wxLONGLONG_TEST_MODE
  642.     m_ll ^= ll.m_ll;
  643.  
  644.     Check();
  645. #endif // wxLONGLONG_TEST_MODE
  646.  
  647.     return *this;
  648. }
  649.  
  650. wxULongLongWx& wxULongLongWx::operator^=(const wxULongLongWx& ll)
  651. {
  652.     m_lo ^= ll.m_lo;
  653.     m_hi ^= ll.m_hi;
  654.  
  655. #ifdef wxLONGLONG_TEST_MODE
  656.     m_ll ^= ll.m_ll;
  657.  
  658.     Check();
  659. #endif // wxLONGLONG_TEST_MODE
  660.  
  661.     return *this;
  662. }
  663.  
  664. wxLongLongWx wxLongLongWx::operator~() const
  665. {
  666.     return wxLongLongWx(~m_hi, ~m_lo);
  667. }
  668.  
  669. wxULongLongWx wxULongLongWx::operator~() const
  670. {
  671.     return wxULongLongWx(~m_hi, ~m_lo);
  672. }
  673.  
  674. // multiplication
  675.  
  676. wxLongLongWx wxLongLongWx::operator*(const wxLongLongWx& ll) const
  677. {
  678.     wxLongLongWx res(*this);
  679.     res *= ll;
  680.  
  681.     return res;
  682. }
  683.  
  684. wxULongLongWx wxULongLongWx::operator*(const wxULongLongWx& ll) const
  685. {
  686.     wxULongLongWx res(*this);
  687.     res *= ll;
  688.  
  689.     return res;
  690. }
  691.  
  692. wxLongLongWx& wxLongLongWx::operator*=(const wxLongLongWx& ll)
  693. {
  694.     wxLongLongWx t(m_hi, m_lo);
  695.     wxLongLongWx q(ll.m_hi, ll.m_lo);
  696.  
  697.     m_hi = m_lo = 0;
  698.  
  699. #ifdef wxLONGLONG_TEST_MODE
  700.     wxLongLong_t llOld = m_ll;
  701.     m_ll = 0;
  702. #endif // wxLONGLONG_TEST_MODE
  703.  
  704.     int counter = 0;
  705.     do
  706.     {
  707.         if ((q.m_lo & 1) != 0)
  708.             *this += t;
  709.         q >>= 1;
  710.         t <<= 1;
  711.         counter++;
  712.     }
  713.     while ((counter < 64) && ((q.m_hi != 0) || (q.m_lo != 0)));
  714.  
  715. #ifdef wxLONGLONG_TEST_MODE
  716.     m_ll = llOld * ll.m_ll;
  717.  
  718.     Check();
  719. #endif // wxLONGLONG_TEST_MODE
  720.  
  721.     return *this;
  722. }
  723.  
  724. wxULongLongWx& wxULongLongWx::operator*=(const wxULongLongWx& ll)
  725. {
  726.     wxULongLongWx t(m_hi, m_lo);
  727.     wxULongLongWx q(ll.m_hi, ll.m_lo);
  728.  
  729.     m_hi = m_lo = 0;
  730.  
  731. #ifdef wxLONGLONG_TEST_MODE
  732.     unsigned wxLongLong_t llOld = m_ll;
  733.     m_ll = 0;
  734. #endif // wxLONGLONG_TEST_MODE
  735.  
  736.     int counter = 0;
  737.     do
  738.     {
  739.         if ((q.m_lo & 1) != 0)
  740.             *this += t;
  741.         q >>= 1;
  742.         t <<= 1;
  743.         counter++;
  744.     }
  745.     while ((counter < 64) && ((q.m_hi != 0) || (q.m_lo != 0)));
  746.  
  747. #ifdef wxLONGLONG_TEST_MODE
  748.     m_ll = llOld * ll.m_ll;
  749.  
  750.     Check();
  751. #endif // wxLONGLONG_TEST_MODE
  752.  
  753.     return *this;
  754. }
  755.  
  756. // division
  757.  
  758. void wxLongLongWx::Divide(const wxLongLongWx& divisorIn,
  759.                           wxLongLongWx& quotient,
  760.                           wxLongLongWx& remainder) const
  761. {
  762.     if ((divisorIn.m_lo == 0) && (divisorIn.m_hi == 0))
  763.     {
  764.         // provoke division by zero error and silence the compilers warnings
  765.         // about an expression without effect and unused variable
  766.         long dummy = divisorIn.m_lo/divisorIn.m_hi;
  767.         dummy += 0;
  768.     }
  769.  
  770.     // VZ: I'm writing this in a hurry and it's surely not the fastest way to
  771.     //     do this - any improvements are more than welcome
  772.     //
  773.     //     code inspired by the snippet at
  774.     //          http://www.bearcave.com/software/divide.htm
  775.     //
  776.     //     Copyright notice:
  777.     //
  778.     //     Use of this program, for any purpose, is granted the author, Ian
  779.     //     Kaplan, as long as this copyright notice is included in the source
  780.     //     code or any source code derived from this program. The user assumes
  781.     //     all responsibility for using this code.
  782.  
  783.     // init everything
  784.     wxLongLongWx dividend = *this,
  785.                  divisor = divisorIn;
  786.  
  787.     quotient = 0l;
  788.     remainder = 0l;
  789.  
  790.     // always do unsigned division and adjust the signs later: in C integer
  791.     // division, the sign of the remainder is the same as the sign of the
  792.     // dividend, while the sign of the quotient is the product of the signs of
  793.     // the dividend and divisor. Of course, we also always have
  794.     //
  795.     //      dividend = quotient*divisor + remainder
  796.     //
  797.     // with 0 <= abs(remainder) < abs(divisor)
  798.     bool negRemainder = dividend.m_hi < 0;
  799.     bool negQuotient = FALSE;   // assume positive
  800.     if ( dividend.m_hi < 0 )
  801.     {
  802.         negQuotient = !negQuotient;
  803.         dividend = -dividend;
  804.     }
  805.     if ( divisor.m_hi < 0 )
  806.     {
  807.         negQuotient = !negQuotient;
  808.         divisor = -divisor;
  809.     }
  810.  
  811.     // check for some particular cases
  812.     if ( divisor > dividend )
  813.     {
  814.         remainder = dividend;
  815.     }
  816.     else if ( divisor == dividend )
  817.     {
  818.         quotient = 1l;
  819.     }
  820.     else
  821.     {
  822.         // here: dividend > divisor and both are positibe: do unsigned division
  823.         size_t nBits = 64u;
  824.         wxLongLongWx d;
  825.  
  826.         #define IS_MSB_SET(ll)  ((ll.m_hi) & (1 << (8*sizeof(long) - 1)))
  827.  
  828.         while ( remainder < divisor )
  829.         {
  830.             remainder <<= 1;
  831.             if ( IS_MSB_SET(dividend) )
  832.             {
  833.                 remainder |= 1;
  834.             }
  835.  
  836.             d = dividend;
  837.             dividend <<= 1;
  838.  
  839.             nBits--;
  840.         }
  841.  
  842.         // undo the last loop iteration
  843.         dividend = d;
  844.         remainder >>= 1;
  845.         nBits++;
  846.  
  847.         for ( size_t i = 0; i < nBits; i++ )
  848.         {
  849.             remainder <<= 1;
  850.             if ( IS_MSB_SET(dividend) )
  851.             {
  852.                 remainder |= 1;
  853.             }
  854.  
  855.             wxLongLongWx t = remainder - divisor;
  856.             dividend <<= 1;
  857.             quotient <<= 1;
  858.             if ( !IS_MSB_SET(t) )
  859.             {
  860.                 quotient |= 1;
  861.  
  862.                 remainder = t;
  863.             }
  864.         }
  865.     }
  866.  
  867.     // adjust signs
  868.     if ( negRemainder )
  869.     {
  870.         remainder = -remainder;
  871.     }
  872.  
  873.     if ( negQuotient )
  874.     {
  875.         quotient = -quotient;
  876.     }
  877. }
  878.  
  879. void wxULongLongWx::Divide(const wxULongLongWx& divisorIn,
  880.                            wxULongLongWx& quotient,
  881.                            wxULongLongWx& remainder) const
  882. {
  883.     if ((divisorIn.m_lo == 0) && (divisorIn.m_hi == 0))
  884.     {
  885.         // provoke division by zero error and silence the compilers warnings
  886.         // about an expression without effect and unused variable
  887.         unsigned long dummy = divisorIn.m_lo/divisorIn.m_hi;
  888.         dummy += 0;
  889.     }
  890.  
  891.     // VZ: I'm writing this in a hurry and it's surely not the fastest way to
  892.     //     do this - any improvements are more than welcome
  893.     //
  894.     //     code inspired by the snippet at
  895.     //          http://www.bearcave.com/software/divide.htm
  896.     //
  897.     //     Copyright notice:
  898.     //
  899.     //     Use of this program, for any purpose, is granted the author, Ian
  900.     //     Kaplan, as long as this copyright notice is included in the source
  901.     //     code or any source code derived from this program. The user assumes
  902.     //     all responsibility for using this code.
  903.  
  904.     // init everything
  905.     wxULongLongWx dividend = *this,
  906.                   divisor = divisorIn;
  907.  
  908.     quotient = 0l;
  909.     remainder = 0l;
  910.  
  911.     // check for some particular cases
  912.     if ( divisor > dividend )
  913.     {
  914.         remainder = dividend;
  915.     }
  916.     else if ( divisor == dividend )
  917.     {
  918.         quotient = 1l;
  919.     }
  920.     else
  921.     {
  922.         // here: dividend > divisor
  923.         size_t nBits = 64u;
  924.         wxULongLongWx d;
  925.  
  926.         #define IS_MSB_SET(ll)  ((ll.m_hi) & (1 << (8*sizeof(long) - 1)))
  927.  
  928.         while ( remainder < divisor )
  929.         {
  930.             remainder <<= 1;
  931.             if ( IS_MSB_SET(dividend) )
  932.             {
  933.                 remainder |= 1;
  934.             }
  935.  
  936.             d = dividend;
  937.             dividend <<= 1;
  938.  
  939.             nBits--;
  940.         }
  941.  
  942.         // undo the last loop iteration
  943.         dividend = d;
  944.         remainder >>= 1;
  945.         nBits++;
  946.  
  947.         for ( size_t i = 0; i < nBits; i++ )
  948.         {
  949.             remainder <<= 1;
  950.             if ( IS_MSB_SET(dividend) )
  951.             {
  952.                 remainder |= 1;
  953.             }
  954.  
  955.             wxULongLongWx t = remainder - divisor;
  956.             dividend <<= 1;
  957.             quotient <<= 1;
  958.             if ( !IS_MSB_SET(t) )
  959.             {
  960.                 quotient |= 1;
  961.  
  962.                 remainder = t;
  963.             }
  964.         }
  965.     }
  966. }
  967.  
  968. wxLongLongWx wxLongLongWx::operator/(const wxLongLongWx& ll) const
  969. {
  970.     wxLongLongWx quotient, remainder;
  971.  
  972.     Divide(ll, quotient, remainder);
  973.  
  974.     return quotient;
  975. }
  976.  
  977. wxULongLongWx wxULongLongWx::operator/(const wxULongLongWx& ll) const
  978. {
  979.     wxULongLongWx quotient, remainder;
  980.  
  981.     Divide(ll, quotient, remainder);
  982.  
  983.     return quotient;
  984. }
  985.  
  986. wxLongLongWx& wxLongLongWx::operator/=(const wxLongLongWx& ll)
  987. {
  988.     wxLongLongWx quotient, remainder;
  989.  
  990.     Divide(ll, quotient, remainder);
  991.  
  992.     *this = quotient;
  993.  
  994.     return *this;
  995. }
  996.  
  997. wxULongLongWx& wxULongLongWx::operator/=(const wxULongLongWx& ll)
  998. {
  999.     wxULongLongWx quotient, remainder;
  1000.  
  1001.     Divide(ll, quotient, remainder);
  1002.  
  1003.     *this = quotient;
  1004.  
  1005.     return *this;
  1006. }
  1007.  
  1008. wxLongLongWx wxLongLongWx::operator%(const wxLongLongWx& ll) const
  1009. {
  1010.     wxLongLongWx quotient, remainder;
  1011.  
  1012.     Divide(ll, quotient, remainder);
  1013.  
  1014.     return remainder;
  1015. }
  1016.  
  1017. wxULongLongWx wxULongLongWx::operator%(const wxULongLongWx& ll) const
  1018. {
  1019.     wxULongLongWx quotient, remainder;
  1020.  
  1021.     Divide(ll, quotient, remainder);
  1022.  
  1023.     return remainder;
  1024. }
  1025.  
  1026. // ----------------------------------------------------------------------------
  1027. // misc
  1028. // ----------------------------------------------------------------------------
  1029.  
  1030. // temporary - just for testing
  1031. void *wxLongLongWx::asArray(void) const
  1032. {
  1033.     static unsigned char temp[8];
  1034.  
  1035.     temp[0] = (char)((m_hi >> 24) & 0xFF);
  1036.     temp[1] = (char)((m_hi >> 16) & 0xFF);
  1037.     temp[2] = (char)((m_hi >> 8)  & 0xFF);
  1038.     temp[3] = (char)((m_hi >> 0)  & 0xFF);
  1039.     temp[4] = (char)((m_lo >> 24) & 0xFF);
  1040.     temp[5] = (char)((m_lo >> 16) & 0xFF);
  1041.     temp[6] = (char)((m_lo >> 8)  & 0xFF);
  1042.     temp[7] = (char)((m_lo >> 0)  & 0xFF);
  1043.  
  1044.     return temp;
  1045. }
  1046.  
  1047. void *wxULongLongWx::asArray(void) const
  1048. {
  1049.     static unsigned char temp[8];
  1050.  
  1051.     temp[0] = (char)((m_hi >> 24) & 0xFF);
  1052.     temp[1] = (char)((m_hi >> 16) & 0xFF);
  1053.     temp[2] = (char)((m_hi >> 8)  & 0xFF);
  1054.     temp[3] = (char)((m_hi >> 0)  & 0xFF);
  1055.     temp[4] = (char)((m_lo >> 24) & 0xFF);
  1056.     temp[5] = (char)((m_lo >> 16) & 0xFF);
  1057.     temp[6] = (char)((m_lo >> 8)  & 0xFF);
  1058.     temp[7] = (char)((m_lo >> 0)  & 0xFF);
  1059.  
  1060.     return temp;
  1061. }
  1062.  
  1063. #endif // wxUSE_LONGLONG_WX
  1064.  
  1065. wxString
  1066. #if wxUSE_LONGLONG_NATIVE
  1067. wxLongLongNative::ToString() const
  1068. #else
  1069. wxLongLongWx::ToString() const
  1070. #endif
  1071. {
  1072.     // TODO: this is awfully inefficient, anything better?
  1073.     wxString result;
  1074.  
  1075.     wxLongLong ll = *this;
  1076.  
  1077.     bool neg;
  1078.     if ( ll < 0 )
  1079.     {
  1080.         ll.Negate();
  1081.         neg = TRUE;
  1082.     }
  1083.     else
  1084.     {
  1085.         neg = FALSE;
  1086.     }
  1087.  
  1088.     while ( ll != 0 )
  1089.     {
  1090.         result.Prepend((wxChar)(_T('0') + (ll % 10).ToLong()));
  1091.         ll /= 10;
  1092.     }
  1093.  
  1094.     if ( result.empty() )
  1095.         result = _T('0');
  1096.     else if ( neg )
  1097.         result.Prepend(_T('-'));
  1098.  
  1099.     return result;
  1100. }
  1101.  
  1102. wxString
  1103. #if wxUSE_LONGLONG_NATIVE
  1104. wxULongLongNative::ToString() const
  1105. #else
  1106. wxULongLongWx::ToString() const
  1107. #endif
  1108. {
  1109.     // TODO: this is awfully inefficient, anything better?
  1110.     wxString result;
  1111.  
  1112.     wxULongLong ll = *this;
  1113.  
  1114.     while ( ll != 0 )
  1115.     {
  1116.         result.Prepend((wxChar)(_T('0') + (ll % 10).ToULong()));
  1117.         ll /= 10;
  1118.     }
  1119.  
  1120.     if ( result.empty() )
  1121.         result = _T('0');
  1122.  
  1123.     return result;
  1124. }
  1125.  
  1126. #if wxUSE_STD_IOSTREAM
  1127.  
  1128. // input/output
  1129. wxSTD ostream& operator<< (wxSTD ostream& o, const wxLongLong& ll)
  1130. {
  1131.     return o << ll.ToString();
  1132. }
  1133.  
  1134. wxSTD ostream& operator<< (wxSTD ostream& o, const wxULongLong& ll)
  1135. {
  1136.     return o << ll.ToString();
  1137. }
  1138.  
  1139. #endif // wxUSE_STD_IOSTREAM
  1140.  
  1141. #endif // wxUSE_LONGLONG
  1142.