]>
git.saurik.com Git - wxWidgets.git/blob - src/common/longlong.cpp
0792e84902c663f7fa8b289710a72c5de500f01f
   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. 
  10 // Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr> 
  11 // Licence:     wxWindows license 
  12 ///////////////////////////////////////////////////////////////////////////// 
  14 // ============================================================================ 
  16 // ============================================================================ 
  19     #pragma implementation "longlong.h" 
  22 #include "wx/wxprec.h" 
  30 #include "wx/longlong.h" 
  32 #include <memory.h>     // for memset() 
  33 #include <math.h>       // for fabs() 
  35 // ============================================================================ 
  37 // ============================================================================ 
  39 #if wxUSE_LONGLONG_NATIVE 
  41 // ---------------------------------------------------------------------------- 
  43 // ---------------------------------------------------------------------------- 
  45 void *wxLongLongNative::asArray(void) const 
  47     static unsigned char temp
[8]; 
  49     temp
[0] = (m_ll 
>> 56) & 0xFF; 
  50     temp
[1] = (m_ll 
>> 48) & 0xFF; 
  51     temp
[2] = (m_ll 
>> 40) & 0xFF; 
  52     temp
[3] = (m_ll 
>> 32) & 0xFF; 
  53     temp
[4] = (m_ll 
>> 24) & 0xFF; 
  54     temp
[5] = (m_ll 
>> 16) & 0xFF; 
  55     temp
[6] = (m_ll 
>> 8)  & 0xFF; 
  56     temp
[7] = (m_ll 
>> 0)  & 0xFF; 
  61 #if wxUSE_STD_IOSTREAM 
  64 ostream
& operator<< (ostream
& o
, const wxLongLongNative
& ll
) 
  68     memset(result
, 'A', 64); 
  72     for (int i 
= 0; i 
< 64; i
++) 
  74         result
[63 - i
] = '0' + (char) ((ll
.m_ll 
>> i
) & 1); 
  80 #endif // wxUSE_STD_IOSTREAM 
  82 #endif // wxUSE_LONGLONG_NATIVE 
  84 // ============================================================================ 
  85 // wxLongLongWx: emulation of 'long long' using 2 longs 
  86 // ============================================================================ 
  91 wxLongLongWx
& wxLongLongWx::Assign(double d
) 
  93     if ( fabs(d
) <= LONG_MAX 
) 
  95         m_hi 
= d 
< 0 ? 1 << (8*sizeof(long) - 1) : 0l; 
 100         wxFAIL_MSG(_T("TODO"));        
 106 wxLongLongWx 
wxLongLongWx::operator<<(int shift
) const 
 112         return wxLongLongWx((m_hi 
<< shift
) | (m_lo 
>> (32 - shift
)), 
 115         return wxLongLongWx(m_lo 
<< (shift 
- 32), 
 119 wxLongLongWx
& wxLongLongWx::operator<<=(int shift
) 
 127         m_hi 
|= m_lo 
>> (32 - shift
); 
 132         m_hi 
= m_lo 
<< (shift 
- 32); 
 139 wxLongLongWx 
wxLongLongWx::operator>>(int shift
) const 
 145         return wxLongLongWx(m_hi 
>> shift
, 
 146                           (m_lo 
>> shift
) | (m_hi 
<< (32 - shift
))); 
 148         return wxLongLongWx((m_hi 
< 0 ? -1l : 0), 
 149                           m_hi 
>> (shift 
- 32)); 
 152 wxLongLongWx
& wxLongLongWx::operator>>=(int shift
) 
 160         m_lo 
|= m_hi 
<< (32 - shift
); 
 165         m_lo 
= m_hi 
>> (shift 
- 32); 
 166         m_hi 
= (m_hi 
< 0 ? -1L : 0); 
 172 wxLongLongWx 
wxLongLongWx::operator+(const wxLongLongWx
& ll
) const 
 176     temp
.m_lo 
= m_lo 
+ ll
.m_lo
; 
 177     temp
.m_hi 
= m_hi 
+ ll
.m_hi
; 
 178     if ((temp
.m_lo 
< m_lo
) || (temp
.m_lo 
< ll
.m_lo
)) 
 184 wxLongLongWx 
wxLongLongWx::operator+(long l
) const 
 188     temp
.m_lo 
= m_lo 
+ l
; 
 193     if ((temp
.m_lo 
< m_lo
) || (temp
.m_lo 
< (unsigned long)l
)) 
 199 wxLongLongWx
& wxLongLongWx::operator+=(const wxLongLongWx
& ll
) 
 201     unsigned long previous 
= m_lo
; 
 206     if ((m_lo 
< previous
) || (m_lo 
< ll
.m_lo
)) 
 212 wxLongLongWx
& wxLongLongWx::operator+=(long l
) 
 214     unsigned long previous 
= m_lo
; 
 220     if ((m_lo 
< previous
) || (m_lo 
< (unsigned long)l
)) 
 227 wxLongLongWx
& wxLongLongWx::operator++() 
 237 wxLongLongWx
& wxLongLongWx::operator++(int) 
 247 wxLongLongWx 
wxLongLongWx::operator-() const 
 249     wxLongLongWx 
temp(~m_hi
, ~m_lo
); 
 260 wxLongLongWx 
wxLongLongWx::operator-(const wxLongLongWx
& ll
) const 
 264     temp
.m_lo 
= m_lo 
- ll
.m_lo
; 
 265     temp
.m_hi 
= m_hi 
- ll
.m_hi
; 
 273 wxLongLongWx
& wxLongLongWx::operator-=(const wxLongLongWx
& ll
) 
 275     unsigned long previous 
= m_lo
; 
 280     if (previous 
< ll
.m_lo
) 
 287 wxLongLongWx
& wxLongLongWx::operator--() 
 290     if (m_lo 
== 0xFFFFFFFF) 
 297 wxLongLongWx
& wxLongLongWx::operator--(int) 
 300     if (m_lo 
== 0xFFFFFFFF) 
 306 // comparison operators 
 308 bool wxLongLongWx::operator<(const wxLongLongWx
& ll
) const 
 310     if ( m_hi 
< ll
.m_hi 
) 
 312     else if ( m_hi 
== ll
.m_hi 
) 
 313         return m_lo 
< ll
.m_lo
; 
 318 bool wxLongLongWx::operator>(const wxLongLongWx
& ll
) const 
 320     if ( m_hi 
> ll
.m_hi 
) 
 322     else if ( m_hi 
== ll
.m_hi 
) 
 323         return m_lo 
> ll
.m_lo
; 
 330 wxLongLongWx 
wxLongLongWx::operator&(const wxLongLongWx
& ll
) const 
 332     return wxLongLongWx(m_hi 
& ll
.m_hi
, m_lo 
& ll
.m_lo
); 
 335 wxLongLongWx 
wxLongLongWx::operator|(const wxLongLongWx
& ll
) const 
 337     return wxLongLongWx(m_hi 
| ll
.m_hi
, m_lo 
| ll
.m_lo
); 
 340 wxLongLongWx 
wxLongLongWx::operator^(const wxLongLongWx
& ll
) const 
 342     return wxLongLongWx(m_hi 
^ ll
.m_hi
, m_lo 
^ ll
.m_lo
); 
 345 wxLongLongWx
& wxLongLongWx::operator&=(const wxLongLongWx
& ll
) 
 353 wxLongLongWx
& wxLongLongWx::operator|=(const wxLongLongWx
& ll
) 
 361 wxLongLongWx
& wxLongLongWx::operator^=(const wxLongLongWx
& ll
) 
 369 wxLongLongWx 
wxLongLongWx::operator~() const 
 371     return wxLongLongWx(~m_hi
, ~m_lo
); 
 376 wxLongLongWx 
wxLongLongWx::operator*(const wxLongLongWx
& ll
) const 
 378     wxLongLongWx 
t(m_hi
, m_lo
); 
 379     wxLongLongWx 
q(ll
.m_hi
, ll
.m_lo
); 
 385         if ((q
.m_lo 
& 1) != 0) 
 391       while ((counter 
< 64) && ((q
.m_hi 
!= 0) || (q
.m_lo 
!= 0))); 
 395 wxLongLongWx
& wxLongLongWx::operator*=(const wxLongLongWx
& ll
) 
 397     wxLongLongWx 
t(m_hi
, m_lo
); 
 398     wxLongLongWx 
q(ll
.m_hi
, ll
.m_lo
); 
 403         if ((q
.m_lo 
& 1) != 0) 
 409       while ((counter 
< 64) && ((q
.m_hi 
!= 0) || (q
.m_lo 
!= 0))); 
 415 void wxLongLongWx::Divide(const wxLongLongWx
& divisorIn
, 
 416                           wxLongLongWx
& quotient
, 
 417                           wxLongLongWx
& remainder
) const 
 419     if ((divisorIn
.m_lo 
== 0) && (divisorIn
.m_hi 
== 0)) 
 421         // provoke division by zero error and silence the compilers warnings 
 422         // about an expression without effect and unused variable 
 423         long dummy 
= divisorIn
.m_lo
/divisorIn
.m_hi
; 
 427     // VZ: I'm writing this in a hurry and it's surely not the fastest way to 
 428     //     do this - any improvements are more than welcome 
 430     //     code inspired by the snippet at 
 431     //          http://www.bearcave.com/software/divide.htm 
 435     //     Use of this program, for any purpose, is granted the author, Ian 
 436     //     Kaplan, as long as this copyright notice is included in the source 
 437     //     code or any source code derived from this program. The user assumes 
 438     //     all responsibility for using this code.  
 441     wxLongLongWx dividend 
= *this, 
 447     // check for some particular cases 
 448     if ( divisor 
> dividend 
) 
 450         remainder 
= dividend
; 
 455     if ( divisor 
== dividend 
) 
 462     // always do unsigned division and adjust the signs later: in C integer 
 463     // division, the sign of the remainder is the same as the sign of the 
 464     // dividend, while the sign of the quotient is the product of the signs of 
 465     // the dividend and divisor. Of course, we also always have 
 467     //      dividend = quotient*divisor + remainder 
 469     // with 0 <= abs(remainder) < abs(divisor) 
 470     bool negRemainder 
= dividend
.m_hi 
< 0; 
 471     bool negQuotient 
= FALSE
;   // assume positive 
 472     if ( dividend
.m_hi 
< 0 ) 
 474         negQuotient 
= !negQuotient
; 
 475         dividend 
= -dividend
; 
 477     if ( divisor
.m_hi 
< 0 ) 
 479         negQuotient 
= !negQuotient
; 
 483     // here: dividend > divisor and both are positibe: do unsigned division 
 487     #define IS_MSB_SET(ll)  ((ll.m_hi) & (1 << (8*sizeof(long) - 1))) 
 489     while ( remainder 
< divisor 
) 
 492         if ( IS_MSB_SET(dividend
) ) 
 503     // undo the last loop iteration 
 508     for ( size_t i 
= 0; i 
< nBits
; i
++ ) 
 511         if ( IS_MSB_SET(dividend
) ) 
 516         wxLongLongWx t 
= remainder 
- divisor
; 
 519         if ( !IS_MSB_SET(t
) ) 
 530         remainder 
= -remainder
; 
 535         quotient 
= -quotient
; 
 539 wxLongLongWx 
wxLongLongWx::operator/(const wxLongLongWx
& ll
) const 
 541     wxLongLongWx quotient
, remainder
; 
 543     Divide(ll
, quotient
, remainder
); 
 548 wxLongLongWx
& wxLongLongWx::operator/=(const wxLongLongWx
& ll
) 
 550     wxLongLongWx quotient
, remainder
; 
 552     Divide(ll
, quotient
, remainder
); 
 554     return *this = quotient
; 
 557 wxLongLongWx 
wxLongLongWx::operator%(const wxLongLongWx
& ll
) const 
 559     wxLongLongWx quotient
, remainder
; 
 561     Divide(ll
, quotient
, remainder
); 
 566 // ---------------------------------------------------------------------------- 
 568 // ---------------------------------------------------------------------------- 
 570 // temporary - just for testing 
 571 void *wxLongLongWx::asArray(void) const 
 573     static unsigned char temp
[8]; 
 575     temp
[0] = (m_hi 
>> 24) & 0xFF; 
 576     temp
[1] = (m_hi 
>> 16) & 0xFF; 
 577     temp
[2] = (m_hi 
>> 8)  & 0xFF; 
 578     temp
[3] = (m_hi 
>> 0)  & 0xFF; 
 579     temp
[4] = (m_lo 
>> 24) & 0xFF; 
 580     temp
[5] = (m_lo 
>> 16) & 0xFF; 
 581     temp
[6] = (m_lo 
>> 8)  & 0xFF; 
 582     temp
[7] = (m_lo 
>> 0)  & 0xFF; 
 587 #if wxUSE_STD_IOSTREAM 
 590 ostream
& operator<< (ostream
& o
, const wxLongLongWx
& ll
) 
 594     memset(result
, 'A', 64); 
 598     for (int i 
= 0; i 
< 32; i
++) 
 600         result
[31 - i
] = (char) ('0' + (int) ((ll
.m_hi 
>> i
) & 1)); 
 601         result
[63 - i
] = (char) ('0' + (int) ((ll
.m_lo 
>> i
) & 1)); 
 606 #endif // wxUSE_STD_IOSTREAM 
 608 #endif // wxUSE_LONGLONG_NATIVE 
 610 #endif // wxUSE_LONGLONG