]>
git.saurik.com Git - wxWidgets.git/blob - src/common/longlong.cpp
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()
34 // ============================================================================
36 // ============================================================================
38 #if wxUSE_LONGLONG_NATIVE
40 // ----------------------------------------------------------------------------
42 // ----------------------------------------------------------------------------
44 void *wxLongLongNative::asArray(void) 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
85 wxLongLongWx
wxLongLongWx::operator<<(int shift
) const
91 return wxLongLongWx((m_hi
<< shift
) | (m_lo
>> (32 - shift
)),
94 return wxLongLongWx(m_lo
<< (shift
- 32),
98 wxLongLongWx
& wxLongLongWx::operator<<=(int shift
)
106 m_hi
|= m_lo
>> (32 - shift
);
111 m_hi
= m_lo
<< (shift
- 32);
118 wxLongLongWx
wxLongLongWx::operator>>(int shift
) const
124 return wxLongLongWx(m_hi
>> shift
,
125 (m_lo
>> shift
) | (m_hi
<< (32 - shift
)));
127 return wxLongLongWx((m_hi
< 0 ? -1l : 0),
128 m_hi
>> (shift
- 32));
131 wxLongLongWx
& wxLongLongWx::operator>>=(int shift
)
139 m_lo
|= m_hi
<< (32 - shift
);
144 m_lo
= m_hi
>> (shift
- 32);
145 m_hi
= (m_hi
< 0 ? -1L : 0);
151 wxLongLongWx
wxLongLongWx::operator+(const wxLongLongWx
& ll
) const
155 temp
.m_lo
= m_lo
+ ll
.m_lo
;
156 temp
.m_hi
= m_hi
+ ll
.m_hi
;
157 if ((temp
.m_lo
< m_lo
) || (temp
.m_lo
< ll
.m_lo
))
163 wxLongLongWx
wxLongLongWx::operator+(long l
) const
167 temp
.m_lo
= m_lo
+ l
;
172 if ((temp
.m_lo
< m_lo
) || (temp
.m_lo
< (unsigned long)l
))
178 wxLongLongWx
& wxLongLongWx::operator+=(const wxLongLongWx
& ll
)
180 unsigned long previous
= m_lo
;
185 if ((m_lo
< previous
) || (m_lo
< ll
.m_lo
))
191 wxLongLongWx
& wxLongLongWx::operator+=(long l
)
193 unsigned long previous
= m_lo
;
199 if ((m_lo
< previous
) || (m_lo
< (unsigned long)l
))
206 wxLongLongWx
& wxLongLongWx::operator++()
216 wxLongLongWx
& wxLongLongWx::operator++(int)
226 wxLongLongWx
wxLongLongWx::operator-() const
228 wxLongLongWx
temp(~m_hi
, ~m_lo
);
239 wxLongLongWx
wxLongLongWx::operator-(const wxLongLongWx
& ll
) const
243 temp
.m_lo
= m_lo
- ll
.m_lo
;
244 temp
.m_hi
= m_hi
- ll
.m_hi
;
252 wxLongLongWx
& wxLongLongWx::operator-=(const wxLongLongWx
& ll
)
254 unsigned long previous
= m_lo
;
259 if (previous
< ll
.m_lo
)
266 wxLongLongWx
& wxLongLongWx::operator--()
269 if (m_lo
== 0xFFFFFFFF)
276 wxLongLongWx
& wxLongLongWx::operator--(int)
279 if (m_lo
== 0xFFFFFFFF)
285 // comparison operators
287 bool wxLongLongWx::operator<(const wxLongLongWx
& ll
) const
289 if ( m_hi
< ll
.m_hi
)
291 else if ( m_hi
== ll
.m_hi
)
292 return m_lo
< ll
.m_lo
;
297 bool wxLongLongWx::operator>(const wxLongLongWx
& ll
) const
299 if ( m_hi
> ll
.m_hi
)
301 else if ( m_hi
== ll
.m_hi
)
302 return m_lo
> ll
.m_lo
;
309 wxLongLongWx
wxLongLongWx::operator&(const wxLongLongWx
& ll
) const
311 return wxLongLongWx(m_hi
& ll
.m_hi
, m_lo
& ll
.m_lo
);
314 wxLongLongWx
wxLongLongWx::operator|(const wxLongLongWx
& ll
) const
316 return wxLongLongWx(m_hi
| ll
.m_hi
, m_lo
| ll
.m_lo
);
319 wxLongLongWx
wxLongLongWx::operator^(const wxLongLongWx
& ll
) const
321 return wxLongLongWx(m_hi
^ ll
.m_hi
, m_lo
^ ll
.m_lo
);
324 wxLongLongWx
& wxLongLongWx::operator&=(const wxLongLongWx
& ll
)
332 wxLongLongWx
& wxLongLongWx::operator|=(const wxLongLongWx
& ll
)
340 wxLongLongWx
& wxLongLongWx::operator^=(const wxLongLongWx
& ll
)
348 wxLongLongWx
wxLongLongWx::operator~() const
350 return wxLongLongWx(~m_hi
, ~m_lo
);
355 wxLongLongWx
wxLongLongWx::operator*(const wxLongLongWx
& ll
) const
357 wxLongLongWx
t(m_hi
, m_lo
);
358 wxLongLongWx
q(ll
.m_hi
, ll
.m_lo
);
364 if ((q
.m_lo
& 1) != 0)
370 while ((counter
< 64) && ((q
.m_hi
!= 0) || (q
.m_lo
!= 0)));
374 wxLongLongWx
& wxLongLongWx::operator*=(const wxLongLongWx
& ll
)
376 wxLongLongWx
t(m_hi
, m_lo
);
377 wxLongLongWx
q(ll
.m_hi
, ll
.m_lo
);
382 if ((q
.m_lo
& 1) != 0)
388 while ((counter
< 64) && ((q
.m_hi
!= 0) || (q
.m_lo
!= 0)));
394 void wxLongLongWx::Divide(const wxLongLongWx
& divisor
,
395 wxLongLongWx
& quotient
,
396 wxLongLongWx
& remainder
) const
398 if ((divisor
.m_lo
== 0) && (divisor
.m_hi
== 0))
400 // provoke division by zero error and silence the compilers warnings
401 // about an expression without effect and unused variable
402 long dummy
= divisor
.m_lo
/divisor
.m_hi
;
406 // VZ: I'm writing this in a hurry and it's surely not the fastest way to
407 // do this - any improvements are more than welcome
409 // the algorithm: first find N such that 2^N * divisor is less than us,
410 // then substract divisor from *this - 2^N * divisor as many times as
413 wxLongLongWx prev
= divisor
;
418 for ( wxLongLongWx tmp
= divisor
; tmp
< remainder
; )
433 while ( remainder
>= prev
)
435 remainder
-= divisor
;
439 // remainder should be in this range at the end
440 wxASSERT_MSG( (0l <= remainder
) && (remainder
< divisor
.Abs()),
441 _T("logic error in wxLongLong division") );
444 wxLongLongWx
wxLongLongWx::operator/(const wxLongLongWx
& ll
) const
446 wxLongLongWx quotient
, remainder
;
448 Divide(ll
, quotient
, remainder
);
453 wxLongLongWx
& wxLongLongWx::operator/=(const wxLongLongWx
& ll
)
455 wxLongLongWx quotient
, remainder
;
457 Divide(ll
, quotient
, remainder
);
459 return *this = quotient
;
462 wxLongLongWx
wxLongLongWx::operator%(const wxLongLongWx
& ll
) const
464 wxLongLongWx quotient
, remainder
;
466 Divide(ll
, quotient
, remainder
);
471 // ----------------------------------------------------------------------------
473 // ----------------------------------------------------------------------------
475 // temporary - just for testing
476 void *wxLongLongWx::asArray(void) const
478 static unsigned char temp
[8];
480 temp
[0] = (m_hi
>> 24) & 0xFF;
481 temp
[1] = (m_hi
>> 16) & 0xFF;
482 temp
[2] = (m_hi
>> 8) & 0xFF;
483 temp
[3] = (m_hi
>> 0) & 0xFF;
484 temp
[4] = (m_lo
>> 24) & 0xFF;
485 temp
[5] = (m_lo
>> 16) & 0xFF;
486 temp
[6] = (m_lo
>> 8) & 0xFF;
487 temp
[7] = (m_lo
>> 0) & 0xFF;
492 #if wxUSE_STD_IOSTREAM
495 ostream
& operator<< (ostream
& o
, const wxLongLongWx
& ll
)
499 memset(result
, 'A', 64);
503 for (int i
= 0; i
< 32; i
++)
505 result
[31 - i
] = (char) ('0' + (int) ((ll
.m_hi
>> i
) & 1));
506 result
[63 - i
] = (char) ('0' + (int) ((ll
.m_lo
>> i
) & 1));
511 #endif // wxUSE_STD_IOSTREAM
513 #endif // wxUSE_LONGLONG_NATIVE
515 #endif // wxUSE_LONGLONG