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 FloatMath {
      7 
      8     static void convTest() {
      9         System.out.println("FloatMath.convTest");
     10 
     11         float f;
     12         double d;
     13         int i;
     14         long l;
     15 
     16         /* float --> int */
     17         f = 1234.5678f;
     18         i = (int) f;
     19         assert(i == 1234);
     20 
     21         f = -1234.5678f;
     22         i = (int) f;
     23         assert(i == -1234);
     24 
     25         /* float --> long */
     26         f = 1238.5678f;
     27         l = (long) f;
     28         assert(l == 1238);
     29 
     30         f = -1238.5678f;
     31         l = (long) f;
     32         assert(l == -1238);
     33 
     34         /* float --> double */
     35         f = 1238.5678f;
     36         d = (double) f;
     37         assert(d > 1238.567 && d < 1238.568);
     38 
     39         /* double --> int */
     40         d = 1234.5678;
     41         i = (int) d;
     42         assert(i == 1234);
     43 
     44         d = -1234.5678;
     45         i = (int) d;
     46         assert(i == -1234);
     47 
     48         /* double --> long */
     49         d = 5678956789.0123;
     50         l = (long) d;
     51         assert(l == 5678956789L);
     52 
     53         d = -5678956789.0123;
     54         l = (long) d;
     55         assert(l == -5678956789L);
     56 
     57         /* double --> float */
     58         d = 1238.5678;
     59         f = (float) d;
     60         assert(f > 1238.567 && f < 1238.568);
     61 
     62         /* int --> long */
     63         i = 7654;
     64         l = (long) i;
     65         assert(l == 7654L);
     66 
     67         i = -7654;
     68         l = (long) i;
     69         assert(l == -7654L);
     70 
     71         /* int --> float */
     72         i = 1234;
     73         f = (float) i;
     74         assert(f > 1233.9f && f < 1234.1f);
     75 
     76         i = -1234;
     77         f = (float) i;
     78         assert(f < -1233.9f && f > -1234.1f);
     79 
     80         /* int --> double */
     81         i = 1238;
     82         d = (double) i;
     83         assert(d > 1237.9f && d < 1238.1f);
     84 
     85         i = -1238;
     86         d = (double) i;
     87         assert(d < -1237.9f && d > -1238.1f);
     88 
     89         /* long --> int (with truncation) */
     90         l = 5678956789L;
     91         i = (int) l;
     92         assert(i == 1383989493);
     93 
     94         l = -5678956789L;
     95         i = (int) l;
     96         assert(i == -1383989493);
     97 
     98         /* long --> float */
     99         l = 5678956789L;
    100         f = (float) l;
    101         assert(f > 5.6789564E9 && f < 5.6789566E9);
    102 
    103         l = -5678956789L;
    104         f = (float) l;
    105         assert(f < -5.6789564E9 && f > -5.6789566E9);
    106 
    107         /* long --> double */
    108         l = 6678956789L;
    109         d = (double) l;
    110         assert(d > 6.6789567E9 && d < 6.6789568E9);
    111 
    112         l = -6678956789L;
    113         d = (double) l;
    114         assert(d < -6.6789567E9 && d > -6.6789568E9);
    115     }
    116 
    117     /*
    118      * We pass in the arguments and return the results so the compiler
    119      * doesn't do the math for us.
    120      */
    121     static float[] floatOperTest(float x, float y) {
    122         System.out.println("FloatMath.floatOperTest");
    123 
    124         float[] results = new float[9];
    125 
    126         /* this seems to generate "op-float" instructions */
    127         results[0] = x + y;
    128         results[1] = x - y;
    129         results[2] = x * y;
    130         results[3] = x / y;
    131         results[4] = x % -y;
    132 
    133         /* this seems to generate "op-float/2addr" instructions */
    134         results[8] = x + (((((x + y) - y) * y) / y) % y);
    135 
    136         return results;
    137     }
    138     static void floatOperCheck(float[] results) {
    139         assert(results[0] > 69996.99f && results[0] < 69997.01f);
    140         assert(results[1] > 70002.99f && results[1] < 70003.01f);
    141         assert(results[2] > -210000.01f && results[2] < -209999.99f);
    142         assert(results[3] > -23333.34f && results[3] < -23333.32f);
    143         assert(results[4] > 0.999f && results[4] < 1.001f);
    144         assert(results[8] > 70000.99f && results[8] < 70001.01f);
    145     }
    146 
    147     /*
    148      * We pass in the arguments and return the results so the compiler
    149      * doesn't do the math for us.
    150      */
    151     static double[] doubleOperTest(double x, double y) {
    152         System.out.println("FloatMath.doubleOperTest");
    153 
    154         double[] results = new double[9];
    155 
    156         /* this seems to generate "op-double" instructions */
    157         results[0] = x + y;
    158         results[1] = x - y;
    159         results[2] = x * y;
    160         results[3] = x / y;
    161         results[4] = x % -y;
    162 
    163         /* this seems to generate "op-double/2addr" instructions */
    164         results[8] = x + (((((x + y) - y) * y) / y) % y);
    165 
    166         return results;
    167     }
    168     static void doubleOperCheck(double[] results) {
    169         assert(results[0] > 69996.99 && results[0] < 69997.01);
    170         assert(results[1] > 70002.99 && results[1] < 70003.01);
    171         assert(results[2] > -210000.01 && results[2] < -209999.99);
    172         assert(results[3] > -23333.34 && results[3] < -23333.32);
    173         assert(results[4] > 0.999 && results[4] < 1.001);
    174         assert(results[8] > 70000.99 && results[8] < 70001.01);
    175     }
    176 
    177     /*
    178      * Try to cause some unary operations.
    179      */
    180     static float unopTest(float f) {
    181         f = -f;
    182         return f;
    183     }
    184 
    185     static int[] convI(long l, float f, double d, float zero) {
    186         int[] results = new int[6];
    187         results[0] = (int) l;
    188         results[1] = (int) f;
    189         results[2] = (int) d;
    190         results[3] = (int) (1.0f / zero);       // +inf
    191         results[4] = (int) (-1.0f / zero);      // -inf
    192         results[5] = (int) ((1.0f / zero) / (1.0f / zero)); // NaN
    193         return results;
    194     }
    195     static void checkConvI(int[] results) {
    196         System.out.println("FloatMath.checkConvI");
    197         assert(results[0] == 0x44332211);
    198         assert(results[1] == 123);
    199         assert(results[2] == -3);
    200         assert(results[3] == 0x7fffffff);
    201         assert(results[4] == 0x80000000);
    202         assert(results[5] == 0);
    203     }
    204 
    205     static long[] convL(int i, float f, double d, double zero) {
    206         long[] results = new long[6];
    207         results[0] = (long) i;
    208         results[1] = (long) f;
    209         results[2] = (long) d;
    210         results[3] = (long) (1.0 / zero);       // +inf
    211         results[4] = (long) (-1.0 / zero);      // -inf
    212         results[5] = (long) ((1.0 / zero) / (1.0 / zero));  // NaN
    213         return results;
    214     }
    215     static void checkConvL(long[] results) {
    216         System.out.println("FloatMath.checkConvL");
    217         assert(results[0] == 0xFFFFFFFF88776655L);
    218         assert(results[1] == 123);
    219         assert(results[2] == -3);
    220         assert(results[3] == 0x7fffffffffffffffL);
    221         assert(results[4] == 0x8000000000000000L);
    222         assert(results[5] == 0);
    223     }
    224 
    225     static float[] convF(int i, long l, double d) {
    226         float[] results = new float[3];
    227         results[0] = (float) i;
    228         results[1] = (float) l;
    229         results[2] = (float) d;
    230         return results;
    231     }
    232     static void checkConvF(float[] results) {
    233         System.out.println("FloatMath.checkConvF");
    234         // TODO: assert values
    235         for (int i = 0; i < results.length; i++)
    236             System.out.println(" " + i + ": " + results[i]);
    237         System.out.println("-2.0054409E9, -8.6133031E18, -3.1415927");
    238     }
    239 
    240     static double[] convD(int i, long l, float f) {
    241         double[] results = new double[3];
    242         results[0] = (double) i;
    243         results[1] = (double) l;
    244         results[2] = (double) f;
    245         return results;
    246     }
    247     static void checkConvD(double[] results) {
    248         System.out.println("FloatMath.checkConvD");
    249         // TODO: assert values
    250         for (int i = 0; i < results.length; i++)
    251             System.out.println(" " + i + ": " + results[i]);
    252         System.out.println("-2.005440939E9, -8.6133032459203287E18, 123.4560012817382");
    253     }
    254 
    255     static void checkConsts() {
    256         System.out.println("FloatMath.checkConsts");
    257 
    258         float f = 10.0f;        // const/special
    259         assert(f > 9.9 && f < 10.1);
    260 
    261         double d = 10.0;        // const-wide/special
    262         assert(d > 9.9 && d < 10.1);
    263     }
    264 
    265     /*
    266      * Determine if two floating point numbers are approximately equal.
    267      *
    268      * (Assumes that floating point is generally working, so we can't use
    269      * this for the first set of tests.)
    270      */
    271     static boolean approxEqual(float a, float b, float maxDelta) {
    272         if (a > b)
    273             return (a - b) < maxDelta;
    274         else
    275             return (b - a) < maxDelta;
    276     }
    277     static boolean approxEqual(double a, double b, double maxDelta) {
    278         if (a > b)
    279             return (a - b) < maxDelta;
    280         else
    281             return (b - a) < maxDelta;
    282     }
    283 
    284     /*
    285      * Test some java.lang.Math functions.
    286      *
    287      * The method arguments are positive values.
    288      */
    289     static void jlmTests(float ff, double dd) {
    290         System.out.println("FloatMath.jlmTests");
    291 
    292         assert(approxEqual(Math.abs(ff), ff, 0.001f));
    293         assert(approxEqual(Math.abs(-ff), ff, 0.001f));
    294         assert(approxEqual(Math.min(ff, -5.0f), -5.0f, 0.001f));
    295         assert(approxEqual(Math.max(ff, -5.0f), ff, 0.001f));
    296 
    297         assert(approxEqual(Math.abs(dd), dd, 0.001));
    298         assert(approxEqual(Math.abs(-dd), dd, 0.001));
    299         assert(approxEqual(Math.min(dd, -5.0), -5.0, 0.001));
    300         assert(approxEqual(Math.max(dd, -5.0), dd, 0.001));
    301 
    302         double sq = Math.sqrt(dd);
    303         assert(approxEqual(sq*sq, dd, 0.001));
    304 
    305         assert(approxEqual(0.5403023058681398, Math.cos(1.0), 0.00000001));
    306         assert(approxEqual(0.8414709848078965, Math.sin(1.0), 0.00000001));
    307     }
    308 
    309     public static void run() {
    310         convTest();
    311 
    312         float[] floatResults;
    313         double[] doubleResults;
    314         int[] intResults;
    315         long[] longResults;
    316 
    317         floatResults = floatOperTest(70000.0f, -3.0f);
    318         floatOperCheck(floatResults);
    319         doubleResults = doubleOperTest(70000.0, -3.0);
    320         doubleOperCheck(doubleResults);
    321 
    322         intResults = convI(0x8877665544332211L, 123.456f, -3.1415926535, 0.0f);
    323         checkConvI(intResults);
    324         longResults = convL(0x88776655, 123.456f, -3.1415926535, 0.0);
    325         checkConvL(longResults);
    326         floatResults = convF(0x88776655, 0x8877665544332211L, -3.1415926535);
    327         checkConvF(floatResults);
    328         doubleResults = convD(0x88776655, 0x8877665544332211L, 123.456f);
    329         checkConvD(doubleResults);
    330 
    331         unopTest(123.456f);
    332 
    333         checkConsts();
    334 
    335         jlmTests(3.14159f, 123456.78987654321);
    336     }
    337 }
    338