• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2006 The Android Open Source Project
2 
3 /**
4  * Test arithmetic operations.
5  */
6 public class IntMath {
7 
shiftTest1()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 
shiftTest2()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 
unsignedShiftTest()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 
convTest()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 
charSubTest()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      */
intOperTest(int x, int y)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     }
intOperCheck(int[] results)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      */
lit16Test(int x)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     }
lit16Check(int[] results)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      */
lit8Test(int x)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     }
lit8Check(int[] results)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      */
intShiftTest(int value, int dist)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     }
intShiftCheck(int[] results)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      */
longOperTest(long x, long y)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     }
longOperCheck(long[] results)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      */
longShiftTest(long value, int dist)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     }
longShiftCheck(long[] results)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      */
unopTest(int x)334     static int unopTest(int x) {
335         x = -x;
336         x ^= 0xffffffff;
337         return x;
338     }
unopCheck(int result)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      */
truncateTest(int x)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     }
truncateCheck(Shorty shorts)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      */
divideByZero(int z)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      */
bigDivideOverflow(int idiv, long ldiv)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      */
checkConsts(byte small, short medium, int large, long huge)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      */
jlmTests(int ii, long ll)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 
run()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 }
493 
494