longlongtest.cpp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Name: tests/longlong/longlong.cpp
  3. // Purpose: wxLongLong unit test
  4. // Author: Vadim Zeitlin, Wlodzimierz ABX Skiba
  5. // Created: 2004-04-01
  6. // Copyright: (c) 2004 Vadim Zeitlin, Wlodzimierz Skiba
  7. ///////////////////////////////////////////////////////////////////////////////
  8. // ----------------------------------------------------------------------------
  9. // headers
  10. // ----------------------------------------------------------------------------
  11. #include "testprec.h"
  12. #ifdef __BORLANDC__
  13. #pragma hdrstop
  14. #endif
  15. #ifndef WX_PRECOMP
  16. #include "wx/wx.h"
  17. #endif // WX_PRECOMP
  18. #include "wx/longlong.h"
  19. #include "wx/timer.h"
  20. #if wxUSE_LONGLONG
  21. // ----------------------------------------------------------------------------
  22. // helpers for testing
  23. // ----------------------------------------------------------------------------
  24. // number of iterations in loops
  25. #define ITEMS 1000
  26. // make a 64 bit number from 4 16 bit ones
  27. #define MAKE_LL(x1, x2, x3, x4) wxLongLong((x1 << 16) | x2, (x3 << 16) | x3)
  28. // get a random 64 bit number
  29. #define RAND_LL() MAKE_LL(rand(), rand(), rand(), rand())
  30. static const long testLongs[] =
  31. {
  32. 0,
  33. 1,
  34. -1,
  35. LONG_MAX,
  36. LONG_MIN,
  37. 0x1234,
  38. -0x1234
  39. };
  40. // ----------------------------------------------------------------------------
  41. // test class
  42. // ----------------------------------------------------------------------------
  43. class LongLongTestCase : public CppUnit::TestCase
  44. {
  45. public:
  46. LongLongTestCase();
  47. private:
  48. CPPUNIT_TEST_SUITE( LongLongTestCase );
  49. CPPUNIT_TEST( Conversion );
  50. CPPUNIT_TEST( Comparison );
  51. CPPUNIT_TEST( Addition );
  52. CPPUNIT_TEST( Multiplication );
  53. CPPUNIT_TEST( Division );
  54. CPPUNIT_TEST( BitOperations );
  55. CPPUNIT_TEST( ToString );
  56. CPPUNIT_TEST( LoHi );
  57. CPPUNIT_TEST( Limits );
  58. CPPUNIT_TEST_SUITE_END();
  59. void Conversion();
  60. void Comparison();
  61. void Addition();
  62. void Multiplication();
  63. void Division();
  64. void BitOperations();
  65. void ToString();
  66. void LoHi();
  67. void Limits();
  68. DECLARE_NO_COPY_CLASS(LongLongTestCase)
  69. };
  70. // register in the unnamed registry so that these tests are run by default
  71. CPPUNIT_TEST_SUITE_REGISTRATION( LongLongTestCase );
  72. // also include in its own registry so that these tests can be run alone
  73. CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( LongLongTestCase, "LongLongTestCase" );
  74. LongLongTestCase::LongLongTestCase()
  75. {
  76. srand((unsigned)time(NULL));
  77. }
  78. void LongLongTestCase::Conversion()
  79. {
  80. for ( size_t n = 0; n < ITEMS; n++ )
  81. {
  82. wxLongLong a = RAND_LL();
  83. wxLongLong b(a.GetHi(), a.GetLo());
  84. CPPUNIT_ASSERT( a == b );
  85. #if wxUSE_LONGLONG_WX
  86. wxLongLongWx c(a.GetHi(), a.GetLo());
  87. CPPUNIT_ASSERT( a == c );
  88. #endif
  89. #if wxUSE_LONGLONG_NATIVE
  90. wxLongLongNative d(a.GetHi(), a.GetLo());
  91. CPPUNIT_ASSERT( a == d );
  92. #endif
  93. }
  94. }
  95. void LongLongTestCase::Comparison()
  96. {
  97. static const long ls[2] =
  98. {
  99. 0x1234,
  100. -0x1234,
  101. };
  102. wxLongLong lls[2];
  103. lls[0] = ls[0];
  104. lls[1] = ls[1];
  105. for ( size_t n = 0; n < WXSIZEOF(testLongs); n++ )
  106. {
  107. for ( size_t m = 0; m < WXSIZEOF(lls); m++ )
  108. {
  109. CPPUNIT_ASSERT( (lls[m] < testLongs[n]) == (ls[m] < testLongs[n]) );
  110. CPPUNIT_ASSERT( (lls[m] > testLongs[n]) == (ls[m] > testLongs[n]) );
  111. CPPUNIT_ASSERT( (lls[m] <= testLongs[n]) == (ls[m] <= testLongs[n]) );
  112. CPPUNIT_ASSERT( (lls[m] >= testLongs[n]) == (ls[m] >= testLongs[n]) );
  113. CPPUNIT_ASSERT( (lls[m] != testLongs[n]) == (ls[m] != testLongs[n]) );
  114. CPPUNIT_ASSERT( (lls[m] == testLongs[n]) == (ls[m] == testLongs[n]) );
  115. }
  116. }
  117. }
  118. void LongLongTestCase::Addition()
  119. {
  120. for ( size_t n = 0; n < ITEMS; n++ )
  121. {
  122. wxLongLong a = RAND_LL();
  123. wxLongLong b = RAND_LL();
  124. wxLongLong c = a + b;
  125. #if wxUSE_LONGLONG_NATIVE
  126. wxLongLongNative a1 = a;
  127. wxLongLongNative b1 = b;
  128. wxLongLongNative c1 = a1 + b1;
  129. CPPUNIT_ASSERT( c == c1 );
  130. #endif
  131. #if wxUSE_LONGLONG_WX
  132. wxLongLongWx a2 = a;
  133. wxLongLongWx b2 = b;
  134. wxLongLongWx c2 = a2 + b2;
  135. CPPUNIT_ASSERT( c == c2 );
  136. #endif
  137. }
  138. }
  139. void LongLongTestCase::Multiplication()
  140. {
  141. for ( size_t n = 0; n < ITEMS; n++ )
  142. {
  143. wxLongLong a = RAND_LL();
  144. wxLongLong b = RAND_LL();
  145. wxLongLong c = a*b;
  146. wxLongLong a1(a.GetHi(), a.GetLo());
  147. wxLongLong b1(b.GetHi(), b.GetLo());
  148. wxLongLong c1 = a1*b1;
  149. CPPUNIT_ASSERT( c1 == c );
  150. #if wxUSE_LONGLONG_WX
  151. wxLongLongWx a2(a.GetHi(), a.GetLo());
  152. wxLongLongWx b2(b.GetHi(), b.GetLo());
  153. wxLongLongWx c2 = a2*b2;
  154. CPPUNIT_ASSERT( c2 == c );
  155. #endif
  156. #if wxUSE_LONGLONG_NATIVE
  157. wxLongLongNative a3(a.GetHi(), a.GetLo());
  158. wxLongLongNative b3(b.GetHi(), b.GetLo());
  159. wxLongLongNative c3 = a3*b3;
  160. CPPUNIT_ASSERT( c3 == c );
  161. #endif
  162. }
  163. }
  164. void LongLongTestCase::Division()
  165. {
  166. for ( size_t n = 0; n < ITEMS; n++ )
  167. {
  168. // get a random wxLongLong (shifting by 12 the MSB ensures that the
  169. // multiplication will not overflow)
  170. wxLongLong a = MAKE_LL((rand() >> 12), rand(), rand(), rand());
  171. // get a random (but non null) long (not wxLongLong for now) divider
  172. long l;
  173. do
  174. {
  175. l = rand();
  176. }
  177. while ( !l );
  178. wxLongLong q = a / l;
  179. wxLongLong r = a % l;
  180. CPPUNIT_ASSERT( a == ( q * l + r ) );
  181. #if wxUSE_LONGLONG_WX
  182. wxLongLongWx a1(a.GetHi(), a.GetLo());
  183. wxLongLongWx q1 = a1 / l;
  184. wxLongLongWx r1 = a1 % l;
  185. CPPUNIT_ASSERT( q == q1 );
  186. CPPUNIT_ASSERT( r == r1 );
  187. CPPUNIT_ASSERT( a1 == ( q1 * l + r1 ) );
  188. #endif
  189. #if wxUSE_LONGLONG_NATIVE
  190. wxLongLongNative a2(a.GetHi(), a.GetLo());
  191. wxLongLongNative q2 = a2 / l;
  192. wxLongLongNative r2 = a2 % l;
  193. CPPUNIT_ASSERT( q == q2 );
  194. CPPUNIT_ASSERT( r == r2 );
  195. CPPUNIT_ASSERT( a2 == ( q2 * l + r2 ) );
  196. #endif
  197. }
  198. }
  199. void LongLongTestCase::BitOperations()
  200. {
  201. for ( size_t m = 0; m < ITEMS; m++ )
  202. {
  203. wxLongLong a = RAND_LL();
  204. for ( size_t n = 0; n < 33; n++ )
  205. {
  206. wxLongLong b(a.GetHi(), a.GetLo()), c, d = b, e;
  207. d >>= n;
  208. c = b >> n;
  209. CPPUNIT_ASSERT( c == d );
  210. d <<= n;
  211. e = c << n;
  212. CPPUNIT_ASSERT( d == e );
  213. #if wxUSE_LONGLONG_WX
  214. wxLongLongWx b1(a.GetHi(), a.GetLo()), c1, d1 = b1, e1;
  215. d1 >>= n;
  216. c1 = b1 >> n;
  217. CPPUNIT_ASSERT( c1 == d1 );
  218. d1 <<= n;
  219. e1 = c1 << n;
  220. CPPUNIT_ASSERT( d1 == e1 );
  221. #endif
  222. #if wxUSE_LONGLONG_NATIVE
  223. wxLongLongNative b2(a.GetHi(), a.GetLo()), c2, d2 = b2, e2;
  224. d2 >>= n;
  225. c2 = b2 >> n;
  226. CPPUNIT_ASSERT( c2 == d2 );
  227. d2 <<= n;
  228. e2 = c2 << n;
  229. CPPUNIT_ASSERT( d2 == e2 );
  230. #endif
  231. }
  232. }
  233. }
  234. void LongLongTestCase::ToString()
  235. {
  236. wxString s1, s2;
  237. for ( size_t n = 0; n < WXSIZEOF(testLongs); n++ )
  238. {
  239. wxLongLong a = testLongs[n];
  240. s1 = wxString::Format(wxT("%ld"), testLongs[n]);
  241. s2 = a.ToString();
  242. CPPUNIT_ASSERT( s1 == s2 );
  243. s2 = wxEmptyString;
  244. s2 << a;
  245. CPPUNIT_ASSERT( s1 == s2 );
  246. #if wxUSE_LONGLONG_WX
  247. wxLongLongWx a1 = testLongs[n];
  248. s2 = a1.ToString();
  249. CPPUNIT_ASSERT( s1 == s2 );
  250. #endif
  251. #if wxUSE_LONGLONG_NATIVE
  252. wxLongLongNative a2 = testLongs[n];
  253. s2 = a2.ToString();
  254. CPPUNIT_ASSERT( s1 == s2 );
  255. #endif
  256. }
  257. wxLongLong a(0x12345678, 0x87654321);
  258. CPPUNIT_ASSERT( a.ToString() == wxT("1311768467139281697") );
  259. a.Negate();
  260. CPPUNIT_ASSERT( a.ToString() == wxT("-1311768467139281697") );
  261. wxLongLong llMin(-2147483647L - 1L, 0);
  262. CPPUNIT_ASSERT( llMin.ToString() == wxT("-9223372036854775808") );
  263. #if wxUSE_LONGLONG_WX
  264. wxLongLongWx a1(a.GetHi(), a.GetLo());
  265. CPPUNIT_ASSERT( a1.ToString() == wxT("-1311768467139281697") );
  266. a1.Negate();
  267. CPPUNIT_ASSERT( a1.ToString() == wxT("1311768467139281697") );
  268. #endif
  269. #if wxUSE_LONGLONG_NATIVE
  270. wxLongLongNative a2(a.GetHi(), a.GetLo());
  271. CPPUNIT_ASSERT( a2.ToString() == wxT("-1311768467139281697") );
  272. a2.Negate();
  273. CPPUNIT_ASSERT( a2.ToString() == wxT("1311768467139281697") );
  274. #endif
  275. }
  276. void LongLongTestCase::LoHi()
  277. {
  278. wxLongLong ll(123, 456);
  279. CPPUNIT_ASSERT_EQUAL( 456u, ll.GetLo() );
  280. CPPUNIT_ASSERT_EQUAL( 123, ll.GetHi() );
  281. wxULongLong ull(987, 654);
  282. CPPUNIT_ASSERT_EQUAL( 654u, ull.GetLo() );
  283. CPPUNIT_ASSERT_EQUAL( 987u, ull.GetHi() );
  284. }
  285. void LongLongTestCase::Limits()
  286. {
  287. // VC6 doesn't specialize numeric_limits<> for __int64 so skip this test
  288. // for it.
  289. #ifndef __VISUALC6__
  290. #if wxUSE_LONGLONG_NATIVE
  291. CPPUNIT_ASSERT( std::numeric_limits<wxLongLong>::is_specialized );
  292. CPPUNIT_ASSERT( std::numeric_limits<wxULongLong>::is_specialized );
  293. wxULongLong maxval = std::numeric_limits<wxULongLong>::max();
  294. CPPUNIT_ASSERT( maxval.ToDouble() > 0 );
  295. #endif // wxUSE_LONGLONG_NATIVE
  296. #endif // !__VISUALC6__
  297. }
  298. #endif // wxUSE_LONGLONG