blob: 89194de90523047074d16b898c9a84ed5352e107 [file] [log] [blame]
jeffhao5d1ac922011-09-29 17:41:15 -07001// Copyright 2006 The Android Open Source Project
2
3/**
4 * Test arithmetic operations.
5 */
6public class IntMath {
7
8 static void shiftTest1() {
9 System.out.println("IntMath.shiftTest1");
10
11 final int[] mBytes = {
12 0x11, 0x22, 0x33, 0x44, 0x88, 0x99, 0xaa, 0xbb
13 };
14 long l;
15 int i1, i2;
16
17 i1 = mBytes[0] | mBytes[1] << 8 | mBytes[2] << 16 | mBytes[3] << 24;
18 i2 = mBytes[4] | mBytes[5] << 8 | mBytes[6] << 16 | mBytes[7] << 24;
19 l = i1 | ((long)i2 << 32);
20
21 assert(i1 == 0x44332211);
22 assert(i2 == 0xbbaa9988);
23 assert(l == 0xbbaa998844332211L);
24
25 l = (long)mBytes[0]
26 | (long)mBytes[1] << 8
27 | (long)mBytes[2] << 16
28 | (long)mBytes[3] << 24
29 | (long)mBytes[4] << 32
30 | (long)mBytes[5] << 40
31 | (long)mBytes[6] << 48
32 | (long)mBytes[7] << 56;
33
34 assert(l == 0xbbaa998844332211L);
35 }
36
37 static void shiftTest2() {
38 System.out.println("IntMath.shiftTest2");
39
40 long a = 0x11;
41 long b = 0x22;
42 long c = 0x33;
43 long d = 0x44;
44 long e = 0x55;
45 long f = 0x66;
46 long g = 0x77;
47 long h = 0x88;
48
49 long result = ((a << 56) | (b << 48) | (c << 40) | (d << 32) |
50 (e << 24) | (f << 16) | (g << 8) | h);
51
52 assert(result == 0x1122334455667788L);
53 }
54
55 static void unsignedShiftTest() {
56 System.out.println("IntMath.unsignedShiftTest");
57
58 byte b = -4;
59 short s = -4;
60 char c = 0xfffc;
61 int i = -4;
62
63 b >>>= 4;
64 s >>>= 4;
65 c >>>= 4;
66 i >>>= 4;
67
68 assert((int) b == -1);
69 assert((int) s == -1);
70 assert((int) c == 0x0fff);
71 assert(i == 268435455);
72 }
73
74 static void convTest() {
75 System.out.println("IntMath.convTest");
76
77 float f;
78 double d;
79 int i;
80 long l;
81
82 /* int --> long */
83 i = 7654;
84 l = (long) i;
85 assert(l == 7654L);
86
87 i = -7654;
88 l = (long) i;
89 assert(l == -7654L);
90
91 /* long --> int (with truncation) */
92 l = 5678956789L;
93 i = (int) l;
94 assert(i == 1383989493);
95
96 l = -5678956789L;
97 i = (int) l;
98 assert(i == -1383989493);
99 }
100
101 static void charSubTest() {
102 System.out.println("IntMath.charSubTest");
103
104 char char1 = 0x00e9;
105 char char2 = 0xffff;
106 int i;
107
108 /* chars are unsigned-expanded to ints before subtraction */
109 i = char1 - char2;
110 assert(i == 0xffff00ea);
111 }
112
113 /*
114 * We pass in the arguments and return the results so the compiler
115 * doesn't do the math for us. (x=70000, y=-3)
116 */
117 static int[] intOperTest(int x, int y) {
118 System.out.println("IntMath.intOperTest");
119
120 int[] results = new int[10];
121
122 /* this seems to generate "op-int" instructions */
123 results[0] = x + y;
124 results[1] = x - y;
125 results[2] = x * y;
126 results[3] = x * x;
127 results[4] = x / y;
128 results[5] = x % -y;
129 results[6] = x & y;
130 results[7] = x | y;
131 results[8] = x ^ y;
132
133 /* this seems to generate "op-int/2addr" instructions */
134 results[9] = x + ((((((((x + y) - y) * y) / y) % y) & y) | y) ^ y);
135
136 return results;
137 }
138 static void intOperCheck(int[] results) {
139 System.out.println("IntMath.intOperCheck");
140
141 /* check this edge case while we're here (div-int/2addr) */
142 int minInt = -2147483648;
143 int negOne = -results[5];
144 int plusOne = 1;
145 int result = (((minInt + plusOne) - plusOne) / negOne) / negOne;
146 assert(result == minInt);
147
148 assert(results[0] == 69997);
149 assert(results[1] == 70003);
150 assert(results[2] == -210000);
151 assert(results[3] == 605032704); // overflow / truncate
152 assert(results[4] == -23333);
153 assert(results[5] == 1);
154 assert(results[6] == 70000);
155 assert(results[7] == -3);
156 assert(results[8] == -70003);
157 assert(results[9] == 70000);
158 }
159
160 /*
161 * More operations, this time with 16-bit constants. (x=77777)
162 */
163 static int[] lit16Test(int x) {
164 System.out.println("IntMath.lit16Test");
165
166 int[] results = new int[8];
167
168 /* try to generate op-int/lit16" instructions */
169 results[0] = x + 1000;
170 results[1] = 1000 - x;
171 results[2] = x * 1000;
172 results[3] = x / 1000;
173 results[4] = x % 1000;
174 results[5] = x & 1000;
175 results[6] = x | -1000;
176 results[7] = x ^ -1000;
177 return results;
178 }
179 static void lit16Check(int[] results) {
180 assert(results[0] == 78777);
181 assert(results[1] == -76777);
182 assert(results[2] == 77777000);
183 assert(results[3] == 77);
184 assert(results[4] == 777);
185 assert(results[5] == 960);
186 assert(results[6] == -39);
187 assert(results[7] == -76855);
188 }
189
190 /*
191 * More operations, this time with 8-bit constants. (x=-55555)
192 */
193 static int[] lit8Test(int x) {
194 System.out.println("IntMath.lit8Test");
195
196 int[] results = new int[8];
197
198 /* try to generate op-int/lit8" instructions */
199 results[0] = x + 10;
200 results[1] = 10 - x;
201 results[2] = x * 10;
202 results[3] = x / 10;
203 results[4] = x % 10;
204 results[5] = x & 10;
205 results[6] = x | -10;
206 results[7] = x ^ -10;
207 return results;
208 }
209 static void lit8Check(int[] results) {
210 //for (int i = 0; i < results.length; i++)
211 // System.out.println(" " + i + ": " + results[i]);
212
213 /* check this edge case while we're here (div-int/lit8) */
214 int minInt = -2147483648;
215 int result = minInt / -1;
216 assert(result == minInt);
217
218 assert(results[0] == -55545);
219 assert(results[1] == 55565);
220 assert(results[2] == -555550);
221 assert(results[3] == -5555);
222 assert(results[4] == -5);
223 assert(results[5] == 8);
224 assert(results[6] == -1);
225 assert(results[7] == 55563);
226 }
227
228
229 /*
230 * Shift some data. (value=0xff00aa01, dist=8)
231 */
232 static int[] intShiftTest(int value, int dist) {
233 System.out.println("IntMath.intShiftTest");
234
235 int results[] = new int[4];
236
237 results[0] = value << dist;
238 results[1] = value >> dist;
239 results[2] = value >>> dist;
240
241 results[3] = (((value << dist) >> dist) >>> dist) << dist;
242 return results;
243 }
244 static void intShiftCheck(int[] results) {
245 System.out.println("IntMath.intShiftCheck");
246
247 assert(results[0] == 0x00aa0100);
248 assert(results[1] == 0xffff00aa);
249 assert(results[2] == 0x00ff00aa);
250 assert(results[3] == 0xaa00);
251 }
252
253 /*
254 * We pass in the arguments and return the results so the compiler
255 * doesn't do the math for us. (x=70000000000, y=-3)
256 */
257 static long[] longOperTest(long x, long y) {
258 System.out.println("IntMath.longOperTest");
259
260 long[] results = new long[10];
261
262 /* this seems to generate "op-long" instructions */
263 results[0] = x + y;
264 results[1] = x - y;
265 results[2] = x * y;
266 results[3] = x * x;
267 results[4] = x / y;
268 results[5] = x % -y;
269 results[6] = x & y;
270 results[7] = x | y;
271 results[8] = x ^ y;
272
273 /* this seems to generate "op-long/2addr" instructions */
274 results[9] = x + ((((((((x + y) - y) * y) / y) % y) & y) | y) ^ y);
275
276 return results;
277 }
278 static void longOperCheck(long[] results) {
279 System.out.println("IntMath.longOperCheck");
280
281 /* check this edge case while we're here (div-long/2addr) */
282 long minLong = -9223372036854775808L;
283 long negOne = -results[5];
284 long plusOne = 1;
285 long result = (((minLong + plusOne) - plusOne) / negOne) / negOne;
286 assert(result == minLong);
287
288 assert(results[0] == 69999999997L);
289 assert(results[1] == 70000000003L);
290 assert(results[2] == -210000000000L);
291 assert(results[3] == -6833923606740729856L); // overflow
292 assert(results[4] == -23333333333L);
293 assert(results[5] == 1);
294 assert(results[6] == 70000000000L);
295 assert(results[7] == -3);
296 assert(results[8] == -70000000003L);
297 assert(results[9] == 70000000000L);
298
299 assert(results.length == 10);
300 }
301
302 /*
303 * Shift some data. (value=0xd5aa96deff00aa01, dist=8)
304 */
305 static long[] longShiftTest(long value, int dist) {
306 System.out.println("IntMath.longShiftTest");
307
308 long results[] = new long[4];
309
310 results[0] = value << dist;
311 results[1] = value >> dist;
312 results[2] = value >>> dist;
313
314 results[3] = (((value << dist) >> dist) >>> dist) << dist;
315 return results;
316 }
317 static long longShiftCheck(long[] results) {
318 System.out.println("IntMath.longShiftCheck");
319
320 assert(results[0] == 0x96deff00aa010000L);
321 assert(results[1] == 0xffffd5aa96deff00L);
322 assert(results[2] == 0x0000d5aa96deff00L);
323 assert(results[3] == 0xffff96deff000000L);
324
325 assert(results.length == 4);
326
327 return results[0]; // test return-long
328 }
329
330
331 /*
332 * Try to cause some unary operations.
333 */
334 static int unopTest(int x) {
335 x = -x;
336 x ^= 0xffffffff;
337 return x;
338 }
339 static void unopCheck(int result) {
340 assert(result == 37);
341 }
342
343 static class Shorty {
344 public short mShort;
345 public char mChar;
346 public byte mByte;
347 };
348
349 /*
350 * Truncate an int.
351 */
352 static Shorty truncateTest(int x) {
353 System.out.println("IntMath.truncateTest");
354 Shorty shorts = new Shorty();
355
356 shorts.mShort = (short) x;
357 shorts.mChar = (char) x;
358 shorts.mByte = (byte) x;
359 return shorts;
360 }
361 static void truncateCheck(Shorty shorts) {
362 assert(shorts.mShort == -5597); // 0xea23
363 assert(shorts.mChar == 59939); // 0xea23
364 assert(shorts.mByte == 35); // 0x23
365 }
366
367 /*
368 * Verify that we get a divide-by-zero exception.
369 */
370 static void divideByZero(int z) {
371 System.out.println("IntMath.divideByZero");
372
373 try {
374 int x = 100 / z;
375 assert(false);
376 } catch (ArithmeticException ae) {
377 }
378
379 try {
380 int x = 100 % z;
381 assert(false);
382 } catch (ArithmeticException ae) {
383 }
384
385 try {
386 long x = 100L / z;
387 assert(false);
388 } catch (ArithmeticException ae) {
389 }
390
391 try {
392 long x = 100L % z;
393 assert(false);
394 } catch (ArithmeticException ae) {
395 }
396 }
397
398 /*
399 * Check an edge condition: dividing the most-negative integer by -1
400 * returns the most-negative integer, and doesn't cause an exception.
401 *
402 * Pass in -1, -1L.
403 */
404 static void bigDivideOverflow(int idiv, long ldiv) {
405 System.out.println("IntMath.bigDivideOverflow");
406 int mostNegInt = (int) 0x80000000;
407 long mostNegLong = (long) 0x8000000000000000L;
408
409 int intDivResult = mostNegInt / idiv;
410 int intModResult = mostNegInt % idiv;
411 long longDivResult = mostNegLong / ldiv;
412 long longModResult = mostNegLong % ldiv;
413
414 assert(intDivResult == mostNegInt);
415 assert(intModResult == 0);
416 assert(longDivResult == mostNegLong);
417 assert(longModResult == 0);
418 }
419
420 /*
421 * Check "const" instructions. We use negative values to ensure that
422 * sign-extension is happening.
423 */
424 static void checkConsts(byte small, short medium, int large, long huge) {
425 System.out.println("IntMath.checkConsts");
426
427 assert(small == 1); // const/4
428 assert(medium == -256); // const/16
429 assert(medium == -256L); // const-wide/16
430 assert(large == -88888); // const
431 assert(large == -88888L); // const-wide/32
432 assert(huge == 0x9922334455667788L); // const-wide
433 }
434
435 /*
436 * Test some java.lang.Math functions.
437 *
438 * The method arguments are positive values.
439 */
440 static void jlmTests(int ii, long ll) {
441 System.out.println("IntMath.jlmTests");
442
443 assert(Math.abs(ii) == ii);
444 assert(Math.abs(-ii) == ii);
445 assert(Math.min(ii, -5) == -5);
446 assert(Math.max(ii, -5) == ii);
447
448 assert(Math.abs(ll) == ll);
449 assert(Math.abs(-ll) == ll);
450 assert(Math.min(ll, -5L) == -5L);
451 assert(Math.max(ll, -5L) == ll);
452 }
453
454 public static void run() {
455 shiftTest1();
456 shiftTest2();
457 unsignedShiftTest();
458 convTest();
459 charSubTest();
460
461 int[] intResults;
462 long[] longResults;
463
464 intResults = intOperTest(70000, -3);
465 intOperCheck(intResults);
466 longResults = longOperTest(70000000000L, -3L);
467 longOperCheck(longResults);
468
469 intResults = lit16Test(77777);
470 lit16Check(intResults);
471 intResults = lit8Test(-55555);
472 lit8Check(intResults);
473
474 intResults = intShiftTest(0xff00aa01, 8);
475 intShiftCheck(intResults);
476 longResults = longShiftTest(0xd5aa96deff00aa01L, 16);
477 long longRet = longShiftCheck(longResults);
478 assert(longRet == 0x96deff00aa010000L);
479
480 Shorty shorts = truncateTest(-16717277); // 0xff00ea23
481 truncateCheck(shorts);
482
483 divideByZero(0);
484 bigDivideOverflow(-1, -1L);
485
486 checkConsts((byte) 1, (short) -256, -88888, 0x9922334455667788L);
487
488 unopCheck(unopTest(38));
489
490 jlmTests(12345, 0x1122334455667788L);
491 }
492}