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