Home | History | Annotate | Download | only in src
      1 // Copyright 2006 The Android Open Source Project
      2 
      3 /**
      4  * Test arithmetic operations.
      5  */
      6 public 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 }
    493