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 convTest()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 */ floatOperTest(float x, float y)135 static float[] floatOperTest(float x, float y) { 136 System.out.println("FloatMath.floatOperTest"); 137 138 float[] results = new float[10]; 139 float tmp; 140 141 /* this seems to generate "op-float" instructions */ 142 results[0] = x + y; 143 results[1] = x - y; 144 results[2] = x * y; 145 results[3] = x / y; 146 results[4] = x % -y; 147 148 /* this seems to generate "op-float/2addr" instructions */ 149 tmp = x; 150 tmp += y; 151 results[5] = tmp; 152 tmp = x; 153 tmp -= y; 154 results[6] = tmp; 155 tmp = x; 156 tmp *= y; 157 results[7] = tmp; 158 tmp = x; 159 tmp /= y; 160 results[8] = tmp; 161 tmp = x; 162 tmp %= -y; 163 results[9] = tmp; 164 165 return results; 166 } floatOperCheck(float[] results)167 static void floatOperCheck(float[] results) { 168 Main.assertTrue(results[0] > 69996.99f && results[0] < 69997.01f); 169 Main.assertTrue(results[1] > 70002.99f && results[1] < 70003.01f); 170 Main.assertTrue(results[2] > -210000.01f && results[2] < -209999.99f); 171 Main.assertTrue(results[3] > -23333.34f && results[3] < -23333.32f); 172 Main.assertTrue(results[4] > 0.999f && results[4] < 1.001f); 173 Main.assertTrue(results[5] > 69996.99f && results[5] < 69997.01f); 174 Main.assertTrue(results[6] > 70002.99f && results[6] < 70003.01f); 175 Main.assertTrue(results[7] > -210000.01f && results[7] < -209999.99f); 176 Main.assertTrue(results[8] > -23333.34f && results[8] < -23333.32f); 177 Main.assertTrue(results[9] > 0.999f && results[9] < 1.001f); 178 } 179 180 /* 181 * We pass in the arguments and return the results so the compiler 182 * doesn't do the math for us. 183 */ doubleOperTest(double x, double y)184 static double[] doubleOperTest(double x, double y) { 185 System.out.println("FloatMath.doubleOperTest"); 186 187 double[] results = new double[10]; 188 double tmp; 189 190 /* this seems to generate "op-double" instructions */ 191 results[0] = x + y; 192 results[1] = x - y; 193 results[2] = x * y; 194 results[3] = x / y; 195 results[4] = x % -y; 196 197 /* this seems to generate "op-double/2addr" instructions */ 198 tmp = x; 199 tmp += y; 200 results[5] = tmp; 201 tmp = x; 202 tmp -= y; 203 results[6] = tmp; 204 tmp = x; 205 tmp *= y; 206 results[7] = tmp; 207 tmp = x; 208 tmp /= y; 209 results[8] = tmp; 210 tmp = x; 211 tmp %= -y; 212 results[9] = tmp; 213 214 return results; 215 } doubleOperCheck(double[] results)216 static void doubleOperCheck(double[] results) { 217 Main.assertTrue(results[0] > 69996.99 && results[0] < 69997.01); 218 Main.assertTrue(results[1] > 70002.99 && results[1] < 70003.01); 219 Main.assertTrue(results[2] > -210000.01 && results[2] < -209999.99); 220 Main.assertTrue(results[3] > -23333.34 && results[3] < -23333.32); 221 Main.assertTrue(results[4] > 0.999 && results[4] < 1.001); 222 Main.assertTrue(results[5] > 69996.99 && results[5] < 69997.01); 223 Main.assertTrue(results[6] > 70002.99 && results[6] < 70003.01); 224 Main.assertTrue(results[7] > -210000.01 && results[7] < -209999.99); 225 Main.assertTrue(results[8] > -23333.34 && results[8] < -23333.32); 226 Main.assertTrue(results[9] > 0.999 && results[9] < 1.001); 227 } 228 229 /* 230 * Try to cause some unary operations. 231 */ unopTest(float f)232 static float unopTest(float f) { 233 f = -f; 234 return f; 235 } 236 convI(long l, float f, double d, float zero)237 static int[] convI(long l, float f, double d, float zero) { 238 int[] results = new int[6]; 239 results[0] = (int) l; 240 results[1] = (int) f; 241 results[2] = (int) d; 242 results[3] = (int) (1.0f / zero); // +inf 243 results[4] = (int) (-1.0f / zero); // -inf 244 results[5] = (int) ((1.0f / zero) / (1.0f / zero)); // NaN 245 return results; 246 } checkConvI(int[] results)247 static void checkConvI(int[] results) { 248 System.out.println("FloatMath.checkConvI"); 249 Main.assertTrue(results[0] == 0x44332211); 250 Main.assertTrue(results[1] == 123); 251 Main.assertTrue(results[2] == -3); 252 Main.assertTrue(results[3] == 0x7fffffff); 253 Main.assertTrue(results[4] == 0x80000000); 254 Main.assertTrue(results[5] == 0); 255 } 256 convL(int i, float f, double d, double zero)257 static long[] convL(int i, float f, double d, double zero) { 258 long[] results = new long[6]; 259 results[0] = (long) i; 260 results[1] = (long) f; 261 results[2] = (long) d; 262 results[3] = (long) (1.0 / zero); // +inf 263 results[4] = (long) (-1.0 / zero); // -inf 264 results[5] = (long) ((1.0 / zero) / (1.0 / zero)); // NaN 265 return results; 266 } checkConvL(long[] results)267 static void checkConvL(long[] results) { 268 System.out.println("FloatMath.checkConvL"); 269 Main.assertTrue(results[0] == 0xFFFFFFFF88776655L); 270 Main.assertTrue(results[1] == 123); 271 Main.assertTrue(results[2] == -3); 272 Main.assertTrue(results[3] == 0x7fffffffffffffffL); 273 Main.assertTrue(results[4] == 0x8000000000000000L); 274 Main.assertTrue(results[5] == 0); 275 } 276 convF(int i, long l, double d)277 static float[] convF(int i, long l, double d) { 278 float[] results = new float[3]; 279 results[0] = (float) i; 280 results[1] = (float) l; 281 results[2] = (float) d; 282 return results; 283 } checkConvF(float[] results)284 static void checkConvF(float[] results) { 285 System.out.println("FloatMath.checkConvF"); 286 Main.assertTrue(results[0] == -2.0054409E9f); 287 Main.assertTrue(results[1] == -8.613303E18f); 288 Main.assertTrue(results[2] == -3.1415927f); 289 } 290 convD(int i, long l, float f)291 static double[] convD(int i, long l, float f) { 292 double[] results = new double[3]; 293 results[0] = (double) i; 294 results[1] = (double) l; 295 results[2] = (double) f; 296 return results; 297 } checkConvD(double[] results)298 static void checkConvD(double[] results) { 299 System.out.println("FloatMath.checkConvD"); 300 Main.assertTrue(results[0] == -2.005440939E9); 301 Main.assertTrue(results[1] == -8.6133032459203287E18); 302 Main.assertTrue(results[2] == 123.45600128173828); 303 } 304 checkConsts()305 static void checkConsts() { 306 System.out.println("FloatMath.checkConsts"); 307 308 float f = 10.0f; // const/special 309 Main.assertTrue(f > 9.9 && f < 10.1); 310 311 double d = 10.0; // const-wide/special 312 Main.assertTrue(d > 9.9 && d < 10.1); 313 } 314 315 /* 316 * Determine if two floating point numbers are approximately equal. 317 * 318 * (Assumes that floating point is generally working, so we can't use 319 * this for the first set of tests.) 320 */ approxEqual(float a, float b, float maxDelta)321 static boolean approxEqual(float a, float b, float maxDelta) { 322 if (a > b) 323 return (a - b) < maxDelta; 324 else 325 return (b - a) < maxDelta; 326 } approxEqual(double a, double b, double maxDelta)327 static boolean approxEqual(double a, double b, double maxDelta) { 328 if (a > b) 329 return (a - b) < maxDelta; 330 else 331 return (b - a) < maxDelta; 332 } 333 334 /* 335 * Test some java.lang.Math functions. 336 * 337 * The method arguments are positive values. 338 */ jlmTests(float ff, double dd)339 static void jlmTests(float ff, double dd) { 340 System.out.println("FloatMath.jlmTests"); 341 342 Main.assertTrue(approxEqual(Math.abs(ff), ff, 0.001f)); 343 Main.assertTrue(approxEqual(Math.abs(-ff), ff, 0.001f)); 344 Main.assertTrue(approxEqual(Math.min(ff, -5.0f), -5.0f, 0.001f)); 345 Main.assertTrue(approxEqual(Math.max(ff, -5.0f), ff, 0.001f)); 346 347 Main.assertTrue(approxEqual(Math.abs(dd), dd, 0.001)); 348 Main.assertTrue(approxEqual(Math.abs(-dd), dd, 0.001)); 349 Main.assertTrue(approxEqual(Math.min(dd, -5.0), -5.0, 0.001)); 350 Main.assertTrue(approxEqual(Math.max(dd, -5.0), dd, 0.001)); 351 352 double sq = Math.sqrt(dd); 353 Main.assertTrue(approxEqual(sq*sq, dd, 0.001)); 354 355 Main.assertTrue(approxEqual(0.5403023058681398, Math.cos(1.0), 0.00000001)); 356 Main.assertTrue(approxEqual(0.8414709848078965, Math.sin(1.0), 0.00000001)); 357 } 358 run()359 public static void run() { 360 convTest(); 361 362 float[] floatResults; 363 double[] doubleResults; 364 int[] intResults; 365 long[] longResults; 366 367 floatResults = floatOperTest(70000.0f, -3.0f); 368 floatOperCheck(floatResults); 369 doubleResults = doubleOperTest(70000.0, -3.0); 370 doubleOperCheck(doubleResults); 371 372 intResults = convI(0x8877665544332211L, 123.456f, -3.1415926535, 0.0f); 373 checkConvI(intResults); 374 longResults = convL(0x88776655, 123.456f, -3.1415926535, 0.0); 375 checkConvL(longResults); 376 floatResults = convF(0x88776655, 0x8877665544332211L, -3.1415926535); 377 checkConvF(floatResults); 378 doubleResults = convD(0x88776655, 0x8877665544332211L, 123.456f); 379 checkConvD(doubleResults); 380 381 unopTest(123.456f); 382 383 checkConsts(); 384 385 jlmTests(3.14159f, 123456.78987654321); 386 } 387 } 388