1 /* 2 * Copyright (C) 2024 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 // Note that $opt$ is a marker for the optimizing compiler to test 18 // it does compile the method, and that $noinline$ is a marker to 19 // test that it does not inline it. 20 21 public class CopySignTest { 22 main()23 public static void main() { 24 copySignFloat(); 25 copySignDouble(); 26 } 27 $opt$noinline$copySignFloat(float a, float b)28 private static float $opt$noinline$copySignFloat(float a, float b) { 29 return Math.copySign(a, b); 30 } 31 copySignFloat()32 private static void copySignFloat() { 33 float testCases [][] = { 34 { +0.0f, 35 Float.MIN_VALUE, 36 0x0.fffffcP-126f, 37 0x0.fffffeP-126f, 38 Float.MIN_NORMAL, 39 1.0f, 40 3.0f, 41 0x1.fffffcP+127f, 42 Float.MAX_VALUE, 43 Float.POSITIVE_INFINITY, 44 Float.NaN 45 }, 46 { Float.NEGATIVE_INFINITY, 47 -Float.MAX_VALUE, 48 -3.0f, 49 -1.0f, 50 -Float.MIN_NORMAL, 51 -0x0.fffffcP-126f, 52 -0x0.fffffeP-126f, 53 -Float.MIN_VALUE, 54 -0.0f, 55 Float.intBitsToFloat(0xFFC00000), // "negative" NaN 56 -0x1.fffffcP+127f 57 } 58 }; 59 60 for (int i = 0; i < 2; i++) { 61 for (int j = 0; j < 2; j++) { 62 for (int m = 0; m < testCases[i].length; m++) { 63 for (int n = 0; n < testCases[j].length; n++) { 64 float expected = (j == 0 ? 1.0f : -1.0f) * Math.abs(testCases[i][m]); 65 66 float calculated = Math.copySign(testCases[i][m], testCases[j][n]); 67 if (Float.isNaN(testCases[i][m])) { 68 assertEquals(calculated, Float.NaN); 69 } else if (Float.isNaN(testCases[j][n])) { 70 assertEquals(Math.abs(calculated), Math.abs(testCases[i][m])); 71 } else { 72 assertEquals(calculated, expected); 73 } 74 75 calculated = $opt$noinline$copySignFloat(testCases[i][m], testCases[j][n]); 76 if (Float.isNaN(testCases[i][m])) { 77 assertEquals(calculated, Float.NaN); 78 } else if (Float.isNaN(testCases[j][n])) { 79 assertEquals(Math.abs(calculated), Math.abs(testCases[i][m])); 80 } else { 81 assertEquals(calculated, expected); 82 } 83 } 84 } 85 } 86 } 87 } 88 $opt$noinline$copySignDouble(double a, double b)89 private static double $opt$noinline$copySignDouble(double a, double b) { 90 return Math.copySign(a, b); 91 } 92 copySignDouble()93 private static void copySignDouble() { 94 double testCases [][] = { 95 { +0.0d, 96 Double.MIN_VALUE, 97 0x0.ffffffffffffeP-1022, 98 0x0.fffffffffffffP-1022, 99 Double.MIN_NORMAL, 100 1.0d, 101 3.0d, 102 0x1.ffffffffffffeP+1023, 103 Double.MAX_VALUE, 104 Double.POSITIVE_INFINITY, 105 Double.NaN 106 }, 107 { Double.NEGATIVE_INFINITY, 108 -Double.MAX_VALUE, 109 -3.0d, 110 -1.0d, 111 -Double.MIN_NORMAL, 112 -0x0.ffffffffffffeP-1022, 113 -0x0.fffffffffffffP-1022, 114 -Double.MIN_VALUE, 115 -0.0d, 116 Double.longBitsToDouble(0xfff8000000000000L), // "negative" NaN 117 -0x1.ffffffffffffeP+1023 118 } 119 }; 120 121 for (int i = 0; i < 2; i++) { 122 for (int j = 0; j < 2; j++) { 123 for (int m = 0; m < testCases[i].length; m++) { 124 for (int n = 0; n < testCases[j].length; n++) { 125 double expected = (j == 0 ? 1.0f : -1.0f) * Math.abs(testCases[i][m]); 126 127 double calculated = Math.copySign(testCases[i][m], testCases[j][n]); 128 if (Double.isNaN(testCases[i][m])) { 129 assertEquals(calculated, Double.NaN); 130 } else if (Double.isNaN(testCases[j][n])) { 131 assertEquals(Math.abs(calculated), Math.abs(testCases[i][m])); 132 } else { 133 assertEquals(calculated, expected); 134 } 135 136 calculated = $opt$noinline$copySignDouble(testCases[i][m], testCases[j][n]); 137 if (Double.isNaN(testCases[i][m])) { 138 assertEquals(calculated, Double.NaN); 139 } else if (Double.isNaN(testCases[j][n])) { 140 assertEquals(Math.abs(calculated), Math.abs(testCases[i][m])); 141 } else { 142 assertEquals(calculated, expected); 143 } 144 } 145 } 146 } 147 } 148 } 149 assertEquals(float calculated, float expected)150 private static void assertEquals(float calculated, float expected) { 151 if (0 != Float.compare(calculated, expected)) { 152 throw new Error("Expected: " + expected + ", found: " + calculated); 153 } 154 } 155 assertEquals(double calculated, double expected)156 private static void assertEquals(double calculated, double expected) { 157 if (0 != Double.compare(calculated, expected)) { 158 throw new Error("Expected: " + expected + ", found: " + calculated); 159 } 160 } 161 162 } 163