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