/Extras/wxWidgets-2.9.0/src/common/longlong.cpp

http://dynamica.googlecode.com/ · C++ · 1363 lines · 981 code · 287 blank · 95 comment · 121 complexity · 6ef8753f503e7f2614bba11fa2b75df4 MD5 · raw file

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