73 {Double.longBitsToDouble(0x7FF8555555555555L), 1.0, NaNd}, 74 {Double.longBitsToDouble(0xFFF8555555555555L), 1.0, NaNd}, 75 {Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL), 1.0, NaNd}, 76 {Double.longBitsToDouble(0xFFFFFFFFFFFFFFFFL), 1.0, NaNd}, 77 {Double.longBitsToDouble(0x7FFDeadBeef00000L), 1.0, NaNd}, 78 {Double.longBitsToDouble(0xFFFDeadBeef00000L), 1.0, NaNd}, 79 {Double.longBitsToDouble(0x7FFCafeBabe00000L), 1.0, NaNd}, 80 {Double.longBitsToDouble(0xFFFCafeBabe00000L), 1.0, NaNd}, 81 }; 82 83 for(int i = 0; i < testCases.length; i++) { 84 failures += testHypotCase(testCases[i][0], testCases[i][1], 85 testCases[i][2]); 86 } 87 88 // Verify hypot(x, 0.0) is close to x over the entire exponent 89 // range. 90 for(int i = DoubleConsts.MIN_SUB_EXPONENT; 91 i <= DoubleConsts.MAX_EXPONENT; 92 i++) { 93 double input = FpUtils.scalb(2, i); 94 failures += testHypotCase(input, 0.0, input); 95 } 96 97 98 // Test Pythagorean triples 99 100 // Small ones 101 for(int m = 1; m < 10; m++) { 102 for(int n = m+1; n < 11; n++) { 103 long [] result = pythagoreanTriple(m, n); 104 failures += testHypotCase(result[0], result[1], result[2]); 105 } 106 } 107 108 // Big ones 109 for(int m = 100000; m < 100100; m++) { 110 for(int n = m+100000; n < 200200; n++) { 111 long [] result = pythagoreanTriple(m, n); 112 failures += testHypotCase(result[0], result[1], result[2]); 113 } 114 } 115 116 // Approaching overflow tests 117 118 /* 119 * Create a random value r with an large-ish exponent. The 120 * result of hypot(3*r, 4*r) should be approximately 5*r. (The 121 * computation of 4*r is exact since it just changes the 122 * exponent). While the exponent of r is less than or equal 123 * to (MAX_EXPONENT - 3), the computation should not overflow. 124 */ 125 java.util.Random rand = new java.util.Random(); 126 for(int i = 0; i < 1000; i++) { 127 double d = rand.nextDouble(); 128 // Scale d to have an exponent equal to MAX_EXPONENT -15 129 d = FpUtils.scalb(d, DoubleConsts.MAX_EXPONENT 130 -15 - FpUtils.ilogb(d)); 131 for(int j = 0; j <= 13; j += 1) { 132 failures += testHypotCase(3*d, 4*d, 5*d, 2.5); 133 d *= 2.0; // increase exponent by 1 134 } 135 } 136 137 // Test for monotonicity failures. Fix one argument and test 138 // two numbers before and two numbers after each chosen value; 139 // i.e. 140 // 141 // pcNeighbors[] = 142 // {nextDown(nextDown(pc)), 143 // nextDown(pc), 144 // pc, 145 // nextUp(pc), 146 // nextUp(nextUp(pc))} 147 // 148 // and we test that hypot(pcNeighbors[i]) <= hypot(pcNeighbors[i+1]) 149 { 150 double pcNeighbors[] = new double[5]; 151 double pcNeighborsHypot[] = new double[5]; 152 double pcNeighborsStrictHypot[] = new double[5]; 153 154 155 for(int i = -18; i <= 18; i++) { 156 double pc = FpUtils.scalb(1.0, i); 157 158 pcNeighbors[2] = pc; 159 pcNeighbors[1] = FpUtils.nextDown(pc); 160 pcNeighbors[0] = FpUtils.nextDown(pcNeighbors[1]); 161 pcNeighbors[3] = FpUtils.nextUp(pc); 162 pcNeighbors[4] = FpUtils.nextUp(pcNeighbors[3]); 163 164 for(int j = 0; j < pcNeighbors.length; j++) { 165 pcNeighborsHypot[j] = Math.hypot(2.0, pcNeighbors[j]); 166 pcNeighborsStrictHypot[j] = StrictMath.hypot(2.0, pcNeighbors[j]); 167 } 168 169 for(int j = 0; j < pcNeighborsHypot.length-1; j++) { 170 if(pcNeighborsHypot[j] > pcNeighborsHypot[j+1] ) { 171 failures++; 172 System.err.println("Monotonicity failure for Math.hypot on " + 173 pcNeighbors[j] + " and " + 174 pcNeighbors[j+1] + "\n\treturned " + 175 pcNeighborsHypot[j] + " and " + 176 pcNeighborsHypot[j+1] ); 177 } 178 179 if(pcNeighborsStrictHypot[j] > pcNeighborsStrictHypot[j+1] ) { 180 failures++; 181 System.err.println("Monotonicity failure for StrictMath.hypot on " + 182 pcNeighbors[j] + " and " + | 73 {Double.longBitsToDouble(0x7FF8555555555555L), 1.0, NaNd}, 74 {Double.longBitsToDouble(0xFFF8555555555555L), 1.0, NaNd}, 75 {Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL), 1.0, NaNd}, 76 {Double.longBitsToDouble(0xFFFFFFFFFFFFFFFFL), 1.0, NaNd}, 77 {Double.longBitsToDouble(0x7FFDeadBeef00000L), 1.0, NaNd}, 78 {Double.longBitsToDouble(0xFFFDeadBeef00000L), 1.0, NaNd}, 79 {Double.longBitsToDouble(0x7FFCafeBabe00000L), 1.0, NaNd}, 80 {Double.longBitsToDouble(0xFFFCafeBabe00000L), 1.0, NaNd}, 81 }; 82 83 for(int i = 0; i < testCases.length; i++) { 84 failures += testHypotCase(testCases[i][0], testCases[i][1], 85 testCases[i][2]); 86 } 87 88 // Verify hypot(x, 0.0) is close to x over the entire exponent 89 // range. 90 for(int i = DoubleConsts.MIN_SUB_EXPONENT; 91 i <= DoubleConsts.MAX_EXPONENT; 92 i++) { 93 double input = Math.scalb(2, i); 94 failures += testHypotCase(input, 0.0, input); 95 } 96 97 98 // Test Pythagorean triples 99 100 // Small ones 101 for(int m = 1; m < 10; m++) { 102 for(int n = m+1; n < 11; n++) { 103 long [] result = pythagoreanTriple(m, n); 104 failures += testHypotCase(result[0], result[1], result[2]); 105 } 106 } 107 108 // Big ones 109 for(int m = 100000; m < 100100; m++) { 110 for(int n = m+100000; n < 200200; n++) { 111 long [] result = pythagoreanTriple(m, n); 112 failures += testHypotCase(result[0], result[1], result[2]); 113 } 114 } 115 116 // Approaching overflow tests 117 118 /* 119 * Create a random value r with an large-ish exponent. The 120 * result of hypot(3*r, 4*r) should be approximately 5*r. (The 121 * computation of 4*r is exact since it just changes the 122 * exponent). While the exponent of r is less than or equal 123 * to (MAX_EXPONENT - 3), the computation should not overflow. 124 */ 125 java.util.Random rand = new java.util.Random(); 126 for(int i = 0; i < 1000; i++) { 127 double d = rand.nextDouble(); 128 // Scale d to have an exponent equal to MAX_EXPONENT -15 129 d = Math.scalb(d, DoubleConsts.MAX_EXPONENT 130 -15 - FpUtils.ilogb(d)); 131 for(int j = 0; j <= 13; j += 1) { 132 failures += testHypotCase(3*d, 4*d, 5*d, 2.5); 133 d *= 2.0; // increase exponent by 1 134 } 135 } 136 137 // Test for monotonicity failures. Fix one argument and test 138 // two numbers before and two numbers after each chosen value; 139 // i.e. 140 // 141 // pcNeighbors[] = 142 // {nextDown(nextDown(pc)), 143 // nextDown(pc), 144 // pc, 145 // nextUp(pc), 146 // nextUp(nextUp(pc))} 147 // 148 // and we test that hypot(pcNeighbors[i]) <= hypot(pcNeighbors[i+1]) 149 { 150 double pcNeighbors[] = new double[5]; 151 double pcNeighborsHypot[] = new double[5]; 152 double pcNeighborsStrictHypot[] = new double[5]; 153 154 155 for(int i = -18; i <= 18; i++) { 156 double pc = Math.scalb(1.0, i); 157 158 pcNeighbors[2] = pc; 159 pcNeighbors[1] = FpUtils.nextDown(pc); 160 pcNeighbors[0] = FpUtils.nextDown(pcNeighbors[1]); 161 pcNeighbors[3] = Math.nextUp(pc); 162 pcNeighbors[4] = Math.nextUp(pcNeighbors[3]); 163 164 for(int j = 0; j < pcNeighbors.length; j++) { 165 pcNeighborsHypot[j] = Math.hypot(2.0, pcNeighbors[j]); 166 pcNeighborsStrictHypot[j] = StrictMath.hypot(2.0, pcNeighbors[j]); 167 } 168 169 for(int j = 0; j < pcNeighborsHypot.length-1; j++) { 170 if(pcNeighborsHypot[j] > pcNeighborsHypot[j+1] ) { 171 failures++; 172 System.err.println("Monotonicity failure for Math.hypot on " + 173 pcNeighbors[j] + " and " + 174 pcNeighbors[j+1] + "\n\treturned " + 175 pcNeighborsHypot[j] + " and " + 176 pcNeighborsHypot[j+1] ); 177 } 178 179 if(pcNeighborsStrictHypot[j] > pcNeighborsStrictHypot[j+1] ) { 180 failures++; 181 System.err.println("Monotonicity failure for StrictMath.hypot on " + 182 pcNeighbors[j] + " and " + |