|
1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of the License "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // e32test\math\t_i64_2.cpp |
|
15 // Overview: |
|
16 // Test 64-bit integer functionality. |
|
17 // API Information: |
|
18 // TInt64, TUInt64. |
|
19 // Details: |
|
20 // - Construct TInt64 and TUInt64 and verify the results. |
|
21 // - Test the unary and shift operators and check results are as expected. |
|
22 // - Test the + - * / and % operators, verify results are as expected. |
|
23 // - Test the + - * / and % operators with random numbers, verify results |
|
24 // are as expected. |
|
25 // - Test the conversion of TInt64 to/from TReal. Verify that the results |
|
26 // are as expected. |
|
27 // - Test the conversion of TInt64 to/from text. Verify that the results |
|
28 // are as expected. |
|
29 // Platforms/Drives/Compatibility: |
|
30 // All. |
|
31 // Assumptions/Requirement/Pre-requisites: |
|
32 // Failures and causes: |
|
33 // Base Port information: |
|
34 // |
|
35 // |
|
36 |
|
37 #include <e32test.h> |
|
38 #include <e32math.h> |
|
39 #include "largeint.h" |
|
40 #include "../misc/prbs.h" |
|
41 |
|
42 typedef TLargeInt<2> I64; |
|
43 typedef TLargeInt<4> I128; |
|
44 |
|
45 RTest test(_L("T_I64_2")); |
|
46 TUint Seed[2]; |
|
47 |
|
48 TUint64 Random64() |
|
49 { |
|
50 TUint h = Random(Seed); |
|
51 TUint l = Random(Seed); |
|
52 return MAKE_TUINT64(h,l); |
|
53 } |
|
54 |
|
55 #define BOOL(x) ((x)?1:0) |
|
56 |
|
57 #define FOREACH(p, table, esize) \ |
|
58 for(p=table; p<(const TUint32*)((const TUint8*)table+sizeof(table)); p+=esize/sizeof(TUint32)) |
|
59 |
|
60 const TUint32 Table1[] = |
|
61 { |
|
62 0x00000000, 0x00000000, |
|
63 0x00000001, 0x00000000, |
|
64 0x0000cc01, 0x00000000, |
|
65 0x00db2701, 0x00000000, |
|
66 0xcc9ffcd1, 0x00000000, |
|
67 0x00000000, 0xffffffff, |
|
68 0xeeeeeeee, 0xffffffff, |
|
69 0x04030201, 0x00000055, |
|
70 0x04030201, 0x00006655, |
|
71 0x04030201, 0x00776655, |
|
72 0x04030201, 0x33776655, |
|
73 0xf9de6484, 0xb504f333 |
|
74 }; |
|
75 |
|
76 void Test1() |
|
77 { |
|
78 test.Next(_L("Unary operators and shifts")); |
|
79 |
|
80 const TUint32* p; |
|
81 FOREACH(p,Table1,8) |
|
82 { |
|
83 I64 a(p); |
|
84 TInt64 b = MAKE_TINT64(p[1], p[0]); |
|
85 I64 c(b); |
|
86 test(a==c); |
|
87 TUint64 d = MAKE_TUINT64(p[1], p[0]); |
|
88 I64 e(d); |
|
89 test(a==e); |
|
90 I64 c2(~b); |
|
91 I64 c3(-b); |
|
92 a.Not(); |
|
93 test(c2==a); |
|
94 a.Not(); |
|
95 test(c==a); |
|
96 a.Neg(); |
|
97 test(c3==a); |
|
98 a.Neg(); |
|
99 test(c==a); |
|
100 } |
|
101 FOREACH(p,Table1,8) |
|
102 { |
|
103 I64 a(p); |
|
104 TInt64 s = MAKE_TINT64(p[1], p[0]); |
|
105 TUint64 u = MAKE_TUINT64(p[1], p[0]); |
|
106 TInt n; |
|
107 for (n=0; n<64; ++n) |
|
108 { |
|
109 I64 b(a), c(a), d(a); |
|
110 b.Lsl(n), c.Lsr(n), d.Asr(n); |
|
111 TInt64 s2 = s<<n; |
|
112 TInt64 s3 = s>>n; |
|
113 TUint64 u2 = u<<n; |
|
114 TUint64 u3 = u>>n; |
|
115 // test.Printf(_L("s2=%lx\ns3=%lx\n,u2=%lx\n,u3=%lx\n"),s2,s3,u2,u3); |
|
116 test(b == I64(s2)); |
|
117 test(b == I64(u2)); |
|
118 test(c == I64(u3)); |
|
119 test(d == I64(s3)); |
|
120 } |
|
121 } |
|
122 } |
|
123 |
|
124 const TUint32 Table2[] = |
|
125 { |
|
126 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
|
127 0x00000001, 0x00000000, 0x00000000, 0x00000000, |
|
128 0x05f5e100, 0x00000000, 0x000000cb, 0x00000000, |
|
129 0xffffff9c, 0xffffffff, 0x00129cbb, 0x00000000, |
|
130 0xffffcd03, 0xffffffff, 0xffff9123, 0xffffffff, |
|
131 0xf9de6484, 0xb504f333, 0xf9de6484, 0xb504f333, |
|
132 0xf9de6484, 0xb504f333, 0x2168c235, 0xc90fdaa2, |
|
133 0xf9de6484, 0xb504f333, 0x000000cb, 0x00000000, |
|
134 0xf9de6484, 0xb504f333, 0x800000cb, 0x00000000, |
|
135 0xf9de6484, 0xb504f333, 0x000000cb, 0x00000001, |
|
136 0xf9de6484, 0xb504f333, 0xfffffed9, 0xffffffff, |
|
137 0xf9de6484, 0xb504f333, 0x197383db, 0xffffffff, |
|
138 0xf9de6484, 0xb504f333, 0x197383db, 0xffffffec, |
|
139 0x38aa3b29, 0x5c17f0bc, 0x000019c7, 0x00000000, |
|
140 0x38aa3b29, 0x5c17f0bc, 0x800019c7, 0x00000000, |
|
141 0x38aa3b29, 0x5c17f0bc, 0x000019c7, 0x00000003, |
|
142 0x38aa3b29, 0x5c17f0bc, 0x197383db, 0xffffffff, |
|
143 0x38aa3b29, 0x5c17f0bc, 0x197383db, 0xffffffec, |
|
144 0x00123456, 0x00000000, 0x8cb9fc1b, 0x00000000, |
|
145 0x00000123, 0x00000000, 0x8cb9fc1b, 0x0000cc9f, |
|
146 0xfffffe33, 0xffffffff, 0x8cb9fc1b, 0x0000cc9f |
|
147 }; |
|
148 |
|
149 void Test2(const TUint32* p) |
|
150 { |
|
151 I64 a(p), b(p+2); |
|
152 TInt64 x = MAKE_TINT64(p[1], p[0]); |
|
153 TInt64 y = MAKE_TINT64(p[3], p[2]); |
|
154 TUint64 u = MAKE_TUINT64(p[1], p[0]); |
|
155 TUint64 v = MAKE_TUINT64(p[3], p[2]); |
|
156 { |
|
157 I64 c(a); c.Add(b); test(c==I64(x+y)); test(c==I64(u+v)); |
|
158 test(c==I64(y+x)); test(c==I64(v+u)); |
|
159 } |
|
160 { |
|
161 I64 c(a); c.Sub(b); test(c==I64(x-y)); test(c==I64(u-v)); |
|
162 I64 d(b); d.Sub(a); test(d==I64(y-x)); test(d==I64(v-u)); |
|
163 } |
|
164 { |
|
165 I64 c(a); c.Mul(b); test(c==I64(x*y)); test(c==I64(u*v)); |
|
166 test(c==I64(y*x)); test(c==I64(v*u)); |
|
167 } |
|
168 { |
|
169 I128 c = a.LongMultS(b); |
|
170 TUint32 t[4]; |
|
171 Math::Mul64(x, y, *(TInt64*)(t+2), *(TUint64*)t); |
|
172 test(c==I128(t)); |
|
173 Math::Mul64(y, x, *(TInt64*)(t+2), *(TUint64*)t); |
|
174 test(c==I128(t)); |
|
175 } |
|
176 { |
|
177 I128 c = a.LongMultU(b); |
|
178 TUint32 t[4]; |
|
179 Math::UMul64(u, v, *(TUint64*)(t+2), *(TUint64*)t); |
|
180 test(c==I128(t)); |
|
181 Math::UMul64(v, u, *(TUint64*)(t+2), *(TUint64*)t); |
|
182 test(c==I128(t)); |
|
183 } |
|
184 if (y!=0) |
|
185 { |
|
186 I64 r; I64 q(a); q.DivS(b,r); |
|
187 test(q==I64(x/y)); |
|
188 test(r==I64(x%y)); |
|
189 TInt64 r2; |
|
190 TInt64 q2 = Math::DivMod64(x, y, r2); |
|
191 test(q==I64(q2)); |
|
192 test(r==I64(r2)); |
|
193 } |
|
194 if (x!=0) |
|
195 { |
|
196 I64 r; I64 q(b); q.DivS(a,r); |
|
197 test(q==I64(y/x)); |
|
198 test(r==I64(y%x)); |
|
199 TInt64 r2; |
|
200 TInt64 q2 = Math::DivMod64(y, x, r2); |
|
201 test(q==I64(q2)); |
|
202 test(r==I64(r2)); |
|
203 } |
|
204 if (v!=0) |
|
205 { |
|
206 I64 r; I64 q(a); q.DivU(b,r); |
|
207 test(q==I64(u/v)); |
|
208 test(r==I64(u%v)); |
|
209 TUint64 r2; |
|
210 TUint64 q2 = Math::UDivMod64(u, v, r2); |
|
211 test(q==I64(q2)); |
|
212 test(r==I64(r2)); |
|
213 } |
|
214 if (u!=0) |
|
215 { |
|
216 I64 r; I64 q(b); q.DivU(a,r); |
|
217 test(q==I64(v/u)); |
|
218 test(r==I64(v%u)); |
|
219 TUint64 r2; |
|
220 TUint64 q2 = Math::UDivMod64(v, u, r2); |
|
221 test(q==I64(q2)); |
|
222 test(r==I64(r2)); |
|
223 } |
|
224 { |
|
225 TInt cmpu = a.CompareU(b); |
|
226 TInt cmps = a.CompareS(b); |
|
227 TInt equ = BOOL(u==v); |
|
228 TInt neu = BOOL(u!=v); |
|
229 TInt hi = BOOL(u>v); |
|
230 TInt hs = BOOL(u>=v); |
|
231 TInt lo = BOOL(u<v); |
|
232 TInt ls = BOOL(u<=v); |
|
233 |
|
234 TInt eqs = BOOL(x==y); |
|
235 TInt nes = BOOL(x!=y); |
|
236 TInt gt = BOOL(x>y); |
|
237 TInt ge = BOOL(x>=y); |
|
238 TInt lt = BOOL(x<y); |
|
239 TInt le = BOOL(x<=y); |
|
240 |
|
241 test(equ==eqs); |
|
242 test(neu==nes); |
|
243 test(equ!=neu); |
|
244 if (cmpu>0) |
|
245 test(!equ && hi && hs && !lo && !ls); |
|
246 else if (cmpu<0) |
|
247 test(!equ && !hi && !hs && lo && ls); |
|
248 else |
|
249 test(equ && !hi && hs && !lo && ls); |
|
250 if (cmps>0) |
|
251 test(!eqs && gt && ge && !lt && !le); |
|
252 else if (cmps<0) |
|
253 test(!eqs && !gt && !ge && lt && le); |
|
254 else |
|
255 test(eqs && !gt && ge && !lt && le); |
|
256 } |
|
257 } |
|
258 |
|
259 void Test2() |
|
260 { |
|
261 test.Next(_L("Test + - * / % (1)")); |
|
262 const TUint32* p; |
|
263 FOREACH(p,Table2,16) |
|
264 { |
|
265 Test2(p); |
|
266 } |
|
267 } |
|
268 |
|
269 void Test3() |
|
270 { |
|
271 test.Next(_L("Test + - * / % (2)")); |
|
272 TInt i; |
|
273 for (i=0; i<100; ++i) |
|
274 { |
|
275 TUint32 p[4]; |
|
276 p[0] = Random(Seed); |
|
277 p[1] = Random(Seed); |
|
278 p[2] = Random(Seed); |
|
279 p[3] = Random(Seed); |
|
280 Test2(p); |
|
281 } |
|
282 } |
|
283 |
|
284 void Test4() |
|
285 { |
|
286 test.Next(_L("Test conversion to/from TReal")); |
|
287 TReal x; |
|
288 TReal limit=1048576.0*1048576.0*8192.0; |
|
289 TInt64 t22 = (TInt64)limit; |
|
290 test(t22 == TInt64(1)<<53); |
|
291 TInt64 t23 = (TInt64)(limit-1.0); |
|
292 test(t23 == (TInt64(1)<<53)-1); |
|
293 |
|
294 |
|
295 TInt i; |
|
296 TInt64 l; |
|
297 for (i=-99; i<100; i++) |
|
298 { |
|
299 x=1; |
|
300 l=1; |
|
301 TReal a(i); |
|
302 TInt64 b(i); |
|
303 while (Abs(x)<limit) |
|
304 { |
|
305 TInt64 ll = (TInt64)x; |
|
306 // test.Printf(_L("r64 %g -> i64 %lx (%lx)\n"), x, ll, l); |
|
307 test(ll==l); |
|
308 ll=0; |
|
309 ll = (TInt64)x; |
|
310 test(ll==l); |
|
311 x*=a; |
|
312 l*=b; |
|
313 if (i==1 || i==0 || (i==-1 && l==TInt64(1))) |
|
314 break; |
|
315 } |
|
316 } |
|
317 |
|
318 TReal i64limit = 1024.0*limit; |
|
319 l=MAKE_TINT64(0x7fffffff,0xfffffc00); |
|
320 x=(TReal)l; |
|
321 test(x==i64limit-1024.0); |
|
322 l=MAKE_TINT64(0x80000000,0x00000000); |
|
323 x=(TReal)l; |
|
324 test(x==-i64limit); |
|
325 l=MAKE_TINT64(0x80000000,0x00000400); |
|
326 x=(TReal)l; |
|
327 test(x==1024.0-i64limit); |
|
328 l=MAKE_TINT64(0x00000001,0x00000000); |
|
329 x=(TReal)l; |
|
330 test(x==65536.0*65536.0); |
|
331 l=MAKE_TINT64(0xffffffff,0x00000000); |
|
332 x=(TReal)l; |
|
333 test(x==-65536.0*65536.0); |
|
334 |
|
335 for (i=-99; i<100; i++) |
|
336 { |
|
337 x=1; |
|
338 l=1; |
|
339 TReal a(i); |
|
340 TInt64 b(i); |
|
341 while (Abs(x)<limit) |
|
342 { |
|
343 TReal y = (TReal)l; |
|
344 test(y==x); |
|
345 x*=a; |
|
346 l*=b; |
|
347 if (i==1 || i==0 || (i==-1 && l==TInt64(1))) |
|
348 break; |
|
349 } |
|
350 } |
|
351 |
|
352 } |
|
353 |
|
354 _LIT8(KTestHex8,"0 1 8 a 1b 2c7 10000000 100000000 1901cbfdc b504f333f9de6484 ffffffffffffffff"); |
|
355 _LIT16(KTestHex16,"0 1 8 a 1b 2c7 10000000 100000000 1901cbfdc b504f333f9de6484 ffffffffffffffff"); |
|
356 |
|
357 const TUint32 TestHexTable[] = |
|
358 { |
|
359 0x00000000, 0x00000000, |
|
360 0x00000001, 0x00000000, |
|
361 0x00000008, 0x00000000, |
|
362 0x0000000a, 0x00000000, |
|
363 0x0000001b, 0x00000000, |
|
364 0x000002c7, 0x00000000, |
|
365 0x10000000, 0x00000000, |
|
366 0x00000000, 0x00000001, |
|
367 0x901cbfdc, 0x00000001, |
|
368 0xf9de6484, 0xb504f333, |
|
369 0xffffffff, 0xffffffff |
|
370 }; |
|
371 |
|
372 _LIT8(KTestDec8,"0 1 8 100 6561 536870912 2147483648 4294967295 4294967296 549755813888 1000000000000000 9223372036854775807 \ |
|
373 -9223372036854775808 -9223372036854775807 -9000000000000000000 -1099511627776 -4294967296 -1000 -1"); |
|
374 _LIT16(KTestDec16,"0 1 8 100 6561 536870912 2147483648 4294967295 4294967296 549755813888 1000000000000000 9223372036854775807 \ |
|
375 -9223372036854775808 -9223372036854775807 -9000000000000000000 -1099511627776 -4294967296 -1000 -1"); |
|
376 |
|
377 const TUint32 TestDecTable[] = |
|
378 { |
|
379 0x00000000, 0x00000000, |
|
380 0x00000001, 0x00000000, |
|
381 0x00000008, 0x00000000, |
|
382 0x00000064, 0x00000000, |
|
383 0x000019a1, 0x00000000, |
|
384 0x20000000, 0x00000000, |
|
385 0x80000000, 0x00000000, |
|
386 0xffffffff, 0x00000000, |
|
387 0x00000000, 0x00000001, |
|
388 0x00000000, 0x00000080, |
|
389 0xa4c68000, 0x00038d7e, |
|
390 0xffffffff, 0x7fffffff, |
|
391 0x00000000, 0x80000000, |
|
392 0x00000001, 0x80000000, |
|
393 0x1d7c0000, 0x831993af, |
|
394 0x00000000, 0xffffff00, |
|
395 0x00000000, 0xffffffff, |
|
396 0xfffffc18, 0xffffffff, |
|
397 0xffffffff, 0xffffffff |
|
398 }; |
|
399 |
|
400 void Test5() |
|
401 { |
|
402 test.Next(_L("Test conversion to/from text")); |
|
403 TLex8 lex8; |
|
404 lex8.Assign(KTestHex8()); |
|
405 TInt64 u; |
|
406 const TUint32* p = TestHexTable; |
|
407 for (; !lex8.Eos(); lex8.SkipSpace(), p+=2) |
|
408 { |
|
409 lex8.Mark(); |
|
410 test(lex8.Val(u,EHex)==KErrNone); |
|
411 test(u == MAKE_TINT64(p[1], p[0])); |
|
412 TPtrC8 text = lex8.MarkedToken(); |
|
413 TBuf8<64> b; |
|
414 b.Num(u,EHex); |
|
415 test(b==text); |
|
416 b.NumUC(u,EHex); |
|
417 TBuf8<64> uc = text; |
|
418 uc.UpperCase(); |
|
419 test(b==uc); |
|
420 } |
|
421 lex8.Assign(KTestDec8()); |
|
422 TInt64 s; |
|
423 p = TestDecTable; |
|
424 for (; !lex8.Eos(); lex8.SkipSpace(), p+=2) |
|
425 { |
|
426 lex8.Mark(); |
|
427 test(lex8.Val(s)==KErrNone); |
|
428 test(s == MAKE_TINT64(p[1], p[0])); |
|
429 TPtrC8 text = lex8.MarkedToken(); |
|
430 TBuf8<64> b; |
|
431 b.Num(s); |
|
432 test(b==text); |
|
433 } |
|
434 |
|
435 TLex16 lex16; |
|
436 lex16.Assign(KTestHex16()); |
|
437 p = TestHexTable; |
|
438 for (; !lex16.Eos(); lex16.SkipSpace(), p+=2) |
|
439 { |
|
440 lex16.Mark(); |
|
441 test(lex16.Val(u,EHex)==KErrNone); |
|
442 test(u == MAKE_TINT64(p[1], p[0])); |
|
443 TPtrC16 text = lex16.MarkedToken(); |
|
444 TBuf16<64> b; |
|
445 b.Num(u,EHex); |
|
446 test(b==text); |
|
447 b.NumUC(u,EHex); |
|
448 TBuf16<64> uc = text; |
|
449 uc.UpperCase(); |
|
450 test(b==uc); |
|
451 } |
|
452 lex16.Assign(KTestDec16()); |
|
453 p = TestDecTable; |
|
454 for (; !lex16.Eos(); lex16.SkipSpace(), p+=2) |
|
455 { |
|
456 lex16.Mark(); |
|
457 test(lex16.Val(s)==KErrNone); |
|
458 test(s == MAKE_TINT64(p[1], p[0])); |
|
459 TPtrC16 text = lex16.MarkedToken(); |
|
460 TBuf16<64> b; |
|
461 b.Num(s); |
|
462 test(b==text); |
|
463 } |
|
464 } |
|
465 |
|
466 GLDEF_C TInt E32Main() |
|
467 { |
|
468 |
|
469 Seed[0] = 0xb8aa3b29; |
|
470 Seed[1] = 0; |
|
471 |
|
472 test.Title(); |
|
473 test.Start(_L("Testing 64 bit integers")); |
|
474 |
|
475 Test1(); |
|
476 Test2(); |
|
477 Test3(); |
|
478 Test4(); |
|
479 Test5(); |
|
480 |
|
481 test.End(); |
|
482 return(KErrNone); |
|
483 } |
|
484 |