]>
git.saurik.com Git - wxWidgets.git/blob - src/common/longlong.cpp
6a0cc8e315a4c91eddd175f102fe634fb649dfa3
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"
29 #include "wx/longlong.h"
31 #include <memory.h> // for memset()
32 #include <math.h> // for fabs()
34 // ============================================================================
36 // ============================================================================
38 #if wxUSE_LONGLONG_NATIVE
40 // ----------------------------------------------------------------------------
42 // ----------------------------------------------------------------------------
44 void *wxLongLongNative::asArray() const
46 static unsigned char temp
[8];
48 temp
[0] = (m_ll
>> 56) & 0xFF;
49 temp
[1] = (m_ll
>> 48) & 0xFF;
50 temp
[2] = (m_ll
>> 40) & 0xFF;
51 temp
[3] = (m_ll
>> 32) & 0xFF;
52 temp
[4] = (m_ll
>> 24) & 0xFF;
53 temp
[5] = (m_ll
>> 16) & 0xFF;
54 temp
[6] = (m_ll
>> 8) & 0xFF;
55 temp
[7] = (m_ll
>> 0) & 0xFF;
60 #if wxUSE_STD_IOSTREAM
63 ostream
& operator<< (ostream
& o
, const wxLongLongNative
& ll
)
67 memset(result
, 'A', 64);
71 for (int i
= 0; i
< 64; i
++)
73 result
[63 - i
] = '0' + (char) ((ll
.m_ll
>> i
) & 1);
79 #endif // wxUSE_STD_IOSTREAM
81 #endif // wxUSE_LONGLONG_NATIVE
83 // ============================================================================
84 // wxLongLongWx: emulation of 'long long' using 2 longs
85 // ============================================================================
90 wxLongLongWx
& wxLongLongWx::Assign(double d
)
92 bool positive
= d
>= 0;
109 wxFAIL_MSG(_T("TODO"));
116 #ifdef wxLONGLONG_TEST_MODE
117 m_ll
= (wxLongLong_t
)d
;
120 #endif // wxLONGLONG_TEST_MODE
125 wxLongLongWx
wxLongLongWx::operator<<(int shift
) const
127 wxLongLongWx
ll(*this);
133 wxLongLongWx
& wxLongLongWx::operator<<=(int shift
)
140 m_hi
|= m_lo
>> (32 - shift
);
145 m_hi
= m_lo
<< (shift
- 32);
150 #ifdef wxLONGLONG_TEST_MODE
154 #endif // wxLONGLONG_TEST_MODE
159 wxLongLongWx
wxLongLongWx::operator>>(int shift
) const
161 wxLongLongWx
ll(*this);
167 wxLongLongWx
& wxLongLongWx::operator>>=(int shift
)
174 m_lo
|= m_hi
<< (32 - shift
);
179 m_lo
= m_hi
>> (shift
- 32);
180 m_hi
= (m_hi
< 0 ? -1L : 0);
184 #ifdef wxLONGLONG_TEST_MODE
188 #endif // wxLONGLONG_TEST_MODE
193 wxLongLongWx
wxLongLongWx::operator+(const wxLongLongWx
& ll
) const
195 wxLongLongWx
res(*this);
201 wxLongLongWx
wxLongLongWx::operator+(long l
) const
203 wxLongLongWx
res(*this);
209 wxLongLongWx
& wxLongLongWx::operator+=(const wxLongLongWx
& ll
)
211 unsigned long previous
= m_lo
;
216 if ((m_lo
< previous
) || (m_lo
< ll
.m_lo
))
219 #ifdef wxLONGLONG_TEST_MODE
223 #endif // wxLONGLONG_TEST_MODE
228 wxLongLongWx
& wxLongLongWx::operator+=(long l
)
230 unsigned long previous
= m_lo
;
236 if ((m_lo
< previous
) || (m_lo
< (unsigned long)l
))
239 #ifdef wxLONGLONG_TEST_MODE
243 #endif // wxLONGLONG_TEST_MODE
249 wxLongLongWx
& wxLongLongWx::operator++()
255 #ifdef wxLONGLONG_TEST_MODE
259 #endif // wxLONGLONG_TEST_MODE
265 wxLongLongWx
wxLongLongWx::operator-() const
267 wxLongLongWx
res(*this);
273 wxLongLongWx
& wxLongLongWx::Negate()
282 #ifdef wxLONGLONG_TEST_MODE
286 #endif // wxLONGLONG_TEST_MODE
293 wxLongLongWx
wxLongLongWx::operator-(const wxLongLongWx
& ll
) const
295 wxLongLongWx
res(*this);
301 wxLongLongWx
& wxLongLongWx::operator-=(const wxLongLongWx
& ll
)
303 unsigned long previous
= m_lo
;
308 if (previous
< ll
.m_lo
)
311 #ifdef wxLONGLONG_TEST_MODE
315 #endif // wxLONGLONG_TEST_MODE
321 wxLongLongWx
& wxLongLongWx::operator--()
324 if (m_lo
== 0xFFFFFFFF)
327 #ifdef wxLONGLONG_TEST_MODE
331 #endif // wxLONGLONG_TEST_MODE
336 // comparison operators
338 bool wxLongLongWx::operator<(const wxLongLongWx
& ll
) const
340 if ( m_hi
< ll
.m_hi
)
342 else if ( m_hi
== ll
.m_hi
)
343 return m_lo
< ll
.m_lo
;
348 bool wxLongLongWx::operator>(const wxLongLongWx
& ll
) const
350 if ( m_hi
> ll
.m_hi
)
352 else if ( m_hi
== ll
.m_hi
)
353 return m_lo
> ll
.m_lo
;
360 wxLongLongWx
wxLongLongWx::operator&(const wxLongLongWx
& ll
) const
362 return wxLongLongWx(m_hi
& ll
.m_hi
, m_lo
& ll
.m_lo
);
365 wxLongLongWx
wxLongLongWx::operator|(const wxLongLongWx
& ll
) const
367 return wxLongLongWx(m_hi
| ll
.m_hi
, m_lo
| ll
.m_lo
);
370 wxLongLongWx
wxLongLongWx::operator^(const wxLongLongWx
& ll
) const
372 return wxLongLongWx(m_hi
^ ll
.m_hi
, m_lo
^ ll
.m_lo
);
375 wxLongLongWx
& wxLongLongWx::operator&=(const wxLongLongWx
& ll
)
380 #ifdef wxLONGLONG_TEST_MODE
384 #endif // wxLONGLONG_TEST_MODE
389 wxLongLongWx
& wxLongLongWx::operator|=(const wxLongLongWx
& ll
)
394 #ifdef wxLONGLONG_TEST_MODE
398 #endif // wxLONGLONG_TEST_MODE
403 wxLongLongWx
& wxLongLongWx::operator^=(const wxLongLongWx
& ll
)
408 #ifdef wxLONGLONG_TEST_MODE
412 #endif // wxLONGLONG_TEST_MODE
417 wxLongLongWx
wxLongLongWx::operator~() const
419 return wxLongLongWx(~m_hi
, ~m_lo
);
424 wxLongLongWx
wxLongLongWx::operator*(const wxLongLongWx
& ll
) const
426 wxLongLongWx
res(*this);
432 wxLongLongWx
& wxLongLongWx::operator*=(const wxLongLongWx
& ll
)
434 wxLongLongWx
t(m_hi
, m_lo
);
435 wxLongLongWx
q(ll
.m_hi
, ll
.m_lo
);
439 #ifdef wxLONGLONG_TEST_MODE
440 wxLongLong_t llOld
= m_ll
;
442 #endif // wxLONGLONG_TEST_MODE
447 if ((q
.m_lo
& 1) != 0)
453 while ((counter
< 64) && ((q
.m_hi
!= 0) || (q
.m_lo
!= 0)));
455 #ifdef wxLONGLONG_TEST_MODE
456 m_ll
= llOld
* ll
.m_ll
;
459 #endif // wxLONGLONG_TEST_MODE
466 void wxLongLongWx::Divide(const wxLongLongWx
& divisorIn
,
467 wxLongLongWx
& quotient
,
468 wxLongLongWx
& remainder
) const
470 if ((divisorIn
.m_lo
== 0) && (divisorIn
.m_hi
== 0))
472 // provoke division by zero error and silence the compilers warnings
473 // about an expression without effect and unused variable
474 long dummy
= divisorIn
.m_lo
/divisorIn
.m_hi
;
478 // VZ: I'm writing this in a hurry and it's surely not the fastest way to
479 // do this - any improvements are more than welcome
481 // code inspired by the snippet at
482 // http://www.bearcave.com/software/divide.htm
486 // Use of this program, for any purpose, is granted the author, Ian
487 // Kaplan, as long as this copyright notice is included in the source
488 // code or any source code derived from this program. The user assumes
489 // all responsibility for using this code.
492 wxLongLongWx dividend
= *this,
498 // always do unsigned division and adjust the signs later: in C integer
499 // division, the sign of the remainder is the same as the sign of the
500 // dividend, while the sign of the quotient is the product of the signs of
501 // the dividend and divisor. Of course, we also always have
503 // dividend = quotient*divisor + remainder
505 // with 0 <= abs(remainder) < abs(divisor)
506 bool negRemainder
= dividend
.m_hi
< 0;
507 bool negQuotient
= FALSE
; // assume positive
508 if ( dividend
.m_hi
< 0 )
510 negQuotient
= !negQuotient
;
511 dividend
= -dividend
;
513 if ( divisor
.m_hi
< 0 )
515 negQuotient
= !negQuotient
;
519 // check for some particular cases
520 if ( divisor
> dividend
)
522 remainder
= dividend
;
524 else if ( divisor
== dividend
)
530 // here: dividend > divisor and both are positibe: do unsigned division
534 #define IS_MSB_SET(ll) ((ll.m_hi) & (1 << (8*sizeof(long) - 1)))
536 while ( remainder
< divisor
)
539 if ( IS_MSB_SET(dividend
) )
550 // undo the last loop iteration
555 for ( size_t i
= 0; i
< nBits
; i
++ )
558 if ( IS_MSB_SET(dividend
) )
563 wxLongLongWx t
= remainder
- divisor
;
566 if ( !IS_MSB_SET(t
) )
578 remainder
= -remainder
;
583 quotient
= -quotient
;
587 wxLongLongWx
wxLongLongWx::operator/(const wxLongLongWx
& ll
) const
589 wxLongLongWx quotient
, remainder
;
591 Divide(ll
, quotient
, remainder
);
596 wxLongLongWx
& wxLongLongWx::operator/=(const wxLongLongWx
& ll
)
598 wxLongLongWx quotient
, remainder
;
600 Divide(ll
, quotient
, remainder
);
602 return *this = quotient
;
605 wxLongLongWx
wxLongLongWx::operator%(const wxLongLongWx
& ll
) const
607 wxLongLongWx quotient
, remainder
;
609 Divide(ll
, quotient
, remainder
);
614 // ----------------------------------------------------------------------------
616 // ----------------------------------------------------------------------------
618 // temporary - just for testing
619 void *wxLongLongWx::asArray(void) const
621 static unsigned char temp
[8];
623 temp
[0] = (char)((m_hi
>> 24) & 0xFF);
624 temp
[1] = (char)((m_hi
>> 16) & 0xFF);
625 temp
[2] = (char)((m_hi
>> 8) & 0xFF);
626 temp
[3] = (char)((m_hi
>> 0) & 0xFF);
627 temp
[4] = (char)((m_lo
>> 24) & 0xFF);
628 temp
[5] = (char)((m_lo
>> 16) & 0xFF);
629 temp
[6] = (char)((m_lo
>> 8) & 0xFF);
630 temp
[7] = (char)((m_lo
>> 0) & 0xFF);
635 #if wxUSE_STD_IOSTREAM
638 ostream
& operator<< (ostream
& o
, const wxLongLongWx
& ll
)
642 memset(result
, 'A', 64);
646 for (int i
= 0; i
< 32; i
++)
648 result
[31 - i
] = (char) ('0' + (int) ((ll
.m_hi
>> i
) & 1));
649 result
[63 - i
] = (char) ('0' + (int) ((ll
.m_lo
>> i
) & 1));
654 #endif // wxUSE_STD_IOSTREAM
656 #endif // wxUSE_LONGLONG_NATIVE
658 #endif // wxUSE_LONGLONG