1 /* 2 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 4851625 4900189 4939441 27 * @summary Tests for {Math, StrictMath}.{sinh, cosh, tanh} 28 * @author Joseph D. Darcy 29 */ 30 package test.java.lang.Math; 31 32 import android.platform.test.annotations.LargeTest; 33 34 import org.testng.annotations.Test; 35 import org.testng.Assert; 36 37 public class HyperbolicTests { 38 HyperbolicTests()39 private HyperbolicTests() { 40 } 41 42 static final double NaNd = Double.NaN; 43 44 /** 45 * Test accuracy of {Math, StrictMath}.sinh. The specified accuracy is 2.5 ulps. 46 * 47 * The definition of sinh(x) is 48 * 49 * (e^x - e^(-x))/2 50 * 51 * The series expansion of sinh(x) = 52 * 53 * x + x^3/3! + x^5/5! + x^7/7! +... 54 * 55 * Therefore, 56 * 57 * 1. For large values of x sinh(x) ~= signum(x)*exp(|x|)/2 58 * 59 * 2. For small values of x, sinh(x) ~= x. 60 * 61 * Additionally, sinh is an odd function; sinh(-x) = -sinh(x). 62 */ 63 @LargeTest 64 @Test testSinh()65 public void testSinh() { 66 /* 67 * Array elements below generated using a quad sinh 68 * implementation. Rounded to a double, the quad result 69 * *should* be correctly rounded, unless we are quite unlucky. 70 * Assuming the quad value is a correctly rounded double, the 71 * allowed error is 3.0 ulps instead of 2.5 since the quad 72 * value rounded to double can have its own 1/2 ulp error. 73 */ 74 double[][] testCases = { 75 // x sinh(x) 76 {0.0625, 0.06254069805219182172183988501029229}, 77 {0.1250, 0.12532577524111545698205754229137154}, 78 {0.1875, 0.18860056562029018382047025055167585}, 79 {0.2500, 0.25261231680816830791412515054205787}, 80 {0.3125, 0.31761115611357728583959867611490292}, 81 {0.3750, 0.38385106791361456875429567642050245}, 82 {0.4375, 0.45159088610312053032509815226723017}, 83 {0.5000, 0.52109530549374736162242562641149155}, 84 {0.5625, 0.59263591611468777373870867338492247}, 85 {0.6250, 0.66649226445661608227260655608302908}, 86 {0.6875, 0.74295294580567543571442036910465007}, 87 {0.7500, 0.82231673193582998070366163444691386}, 88 {0.8125, 0.90489373856606433650504536421491368}, 89 {0.8750, 0.99100663714429475605317427568995231}, 90 {0.9375, 1.08099191569306394011007867453992548}, 91 {1.0000, 1.17520119364380145688238185059560082}, 92 {1.0625, 1.27400259579739321279181130344911907}, 93 {1.1250, 1.37778219077984075760379987065228373}, 94 {1.1875, 1.48694549961380717221109202361777593}, 95 {1.2500, 1.60191908030082563790283030151221415}, 96 {1.3125, 1.72315219460596010219069206464391528}, 97 {1.3750, 1.85111856355791532419998548438506416}, 98 {1.4375, 1.98631821852425112898943304217629457}, 99 {1.5000, 2.12927945509481749683438749467763195}, 100 {1.5625, 2.28056089740825247058075476705718764}, 101 {1.6250, 2.44075368098794353221372986997161132}, 102 {1.6875, 2.61048376261693140366028569794027603}, 103 {1.7500, 2.79041436627764265509289122308816092}, 104 {1.8125, 2.98124857471401377943765253243875520}, 105 {1.8750, 3.18373207674259205101326780071803724}, 106 {1.9375, 3.39865608104779099764440244167531810}, 107 {2.0000, 3.62686040784701876766821398280126192}, 108 {2.0625, 3.86923677050642806693938384073620450}, 109 {2.1250, 4.12673225993027252260441410537905269}, 110 {2.1875, 4.40035304533919660406976249684469164}, 111 {2.2500, 4.69116830589833069188357567763552003}, 112 {2.3125, 5.00031440855811351554075363240262157}, 113 {2.3750, 5.32899934843284576394645856548481489}, 114 {2.4375, 5.67850746906785056212578751630266858}, 115 {2.5000, 6.05020448103978732145032363835040319}, 116 {2.5625, 6.44554279850040875063706020260185553}, 117 {2.6250, 6.86606721451642172826145238779845813}, 118 {2.6875, 7.31342093738196587585692115636603571}, 119 {2.7500, 7.78935201149073201875513401029935330}, 120 {2.8125, 8.29572014785741787167717932988491961}, 121 {2.8750, 8.83450399097893197351853322827892144}, 122 {2.9375, 9.40780885043076394429977972921690859}, 123 {3.0000, 10.01787492740990189897459361946582867}, 124 {3.0625, 10.66708606836969224165124519209968368}, 125 {3.1250, 11.35797907995166028304704128775698426}, 126 {3.1875, 12.09325364161259019614431093344260209}, 127 {3.2500, 12.87578285468067003959660391705481220}, 128 {3.3125, 13.70862446906136798063935858393686525}, 129 {3.3750, 14.59503283146163690015482636921657975}, 130 {3.4375, 15.53847160182039311025096666980558478}, 131 {3.5000, 16.54262728763499762495673152901249743}, 132 {3.5625, 17.61142364906941482858466494889121694}, 133 {3.6250, 18.74903703113232171399165788088277979}, 134 {3.6875, 19.95991268283598684128844120984214675}, 135 {3.7500, 21.24878212710338697364101071825171163}, 136 {3.8125, 22.62068164929685091969259499078125023}, 137 {3.8750, 24.08097197661255803883403419733891573}, 138 {3.9375, 25.63535922523855307175060244757748997}, 139 {4.0000, 27.28991719712775244890827159079382096}, 140 {4.0625, 29.05111111351106713777825462100160185}, 141 {4.1250, 30.92582287788986031725487699744107092}, 142 {4.1875, 32.92137796722343190618721270937061472}, 143 {4.2500, 35.04557405638942942322929652461901154}, 144 {4.3125, 37.30671148776788628118833357170042385}, 145 {4.3750, 39.71362570500944929025069048612806024}, 146 {4.4375, 42.27572177772344954814418332587050658}, 147 {4.5000, 45.00301115199178562180965680564371424}, 148 {4.5625, 47.90615077031205065685078058248081891}, 149 {4.6250, 50.99648471383193131253995134526177467}, 150 {4.6875, 54.28608852959281437757368957713936555}, 151 {4.7500, 57.78781641599226874961859781628591635}, 152 {4.8125, 61.51535145084362283008545918273109379}, 153 {4.8750, 65.48325905829987165560146562921543361}, 154 {4.9375, 69.70704392356508084094318094283346381}, 155 {5.0000, 74.20321057778875897700947199606456364}, 156 {5.0625, 78.98932788987998983462810080907521151}, 157 {5.1250, 84.08409771724448958901392613147384951}, 158 {5.1875, 89.50742798369883598816307922895346849}, 159 {5.2500, 95.28051047011540739630959111303975956}, 160 {5.3125, 101.42590362176666730633859252034238987}, 161 {5.3750, 107.96762069594029162704530843962700133}, 162 {5.4375, 114.93122359426386042048760580590182604}, 163 {5.5000, 122.34392274639096192409774240457730721}, 164 {5.5625, 130.23468343534638291488502321709913206}, 165 {5.6250, 138.63433897999898233879574111119546728}, 166 {5.6875, 147.57571121692522056519568264304815790}, 167 {5.7500, 157.09373875244884423880085377625986165}, 168 {5.8125, 167.22561348600435888568183143777868662}, 169 {5.8750, 178.01092593829229887752609866133883987}, 170 {5.9375, 189.49181995209921964640216682906501778}, 171 {6.0000, 201.71315737027922812498206768797872263}, 172 {6.0625, 214.72269333437984291483666459592578915}, 173 {6.1250, 228.57126288889537420461281285729970085}, 174 {6.1875, 243.31297962030799867970551767086092471}, 175 {6.2500, 259.00544710710289911522315435345489966}, 176 {6.3125, 275.70998400700299790136562219920451185}, 177 {6.3750, 293.49186366095654566861661249898332253}, 178 {6.4375, 312.42056915013535342987623229485223434}, 179 {6.5000, 332.57006480258443156075705566965111346}, 180 {6.5625, 354.01908521044116928437570109827956007}, 181 {6.6250, 376.85144288706511933454985188849781703}, 182 {6.6875, 401.15635576625530823119100750634165252}, 183 {6.7500, 427.02879582326538080306830640235938517}, 184 {6.8125, 454.56986017986077163530945733572724452}, 185 {6.8750, 483.88716614351897894746751705315210621}, 186 {6.9375, 515.09527172439720070161654727225752288}, 187 {7.0000, 548.31612327324652237375611757601851598}, 188 {7.0625, 583.67953198942753384680988096024373270}, 189 {7.1250, 621.32368116099280160364794462812762880}, 190 {7.1875, 661.39566611888784148449430491465857519}, 191 {7.2500, 704.05206901515336623551137120663358760}, 192 {7.3125, 749.45957067108712382864538206200700256}, 193 {7.3750, 797.79560188617531521347351754559776282}, 194 {7.4375, 849.24903675279739482863565789325699416}, 195 {7.5000, 904.02093068584652953510919038935849651}, 196 {7.5625, 962.32530605113249628368993221570636328}, 197 {7.6250, 1024.38998846242707559349318193113614698}, 198 {7.6875, 1090.45749701500081956792547346904792325}, 199 {7.7500, 1160.78599193425808533255719118417856088}, 200 {7.8125, 1235.65028334242796895820912936318532502}, 201 {7.8750, 1315.34290508508890654067255740428824014}, 202 {7.9375, 1400.17525781352742299995139486063802583}, 203 {8.0000, 1490.47882578955018611587663903188144796}, 204 {8.0625, 1586.60647216744061169450001100145859236}, 205 {8.1250, 1688.93381781440241350635231605477507900}, 206 {8.1875, 1797.86070905726094477721128358866360644}, 207 {8.2500, 1913.81278009067446281883262689250118009}, 208 {8.3125, 2037.24311615199935553277163192983440062}, 209 {8.3750, 2168.63402396170125867037749369723761636}, 210 {8.4375, 2308.49891634734644432370720900969004306}, 211 {8.5000, 2457.38431841538268239359965370719928775}, 212 {8.5625, 2615.87200310986940554256648824234335262}, 213 {8.6250, 2784.58126450289932429469130598902487336}, 214 {8.6875, 2964.17133769964321637973459949999057146}, 215 {8.7500, 3155.34397481384944060352507473513108710}, 216 {8.8125, 3358.84618707947841898217318996045550438}, 217 {8.8750, 3575.47316381333288862617411467285480067}, 218 {8.9375, 3806.07137963459383403903729660349293583}, 219 {9.0000, 4051.54190208278996051522359589803425598}, 220 {9.0625, 4312.84391255878980330955246931164633615}, 221 {9.1250, 4590.99845434696991399363282718106006883}, 222 {9.1875, 4887.09242236403719571363798584676797558}, 223 {9.2500, 5202.28281022453561319352901552085348309}, 224 {9.3125, 5537.80123121853803935727335892054791265}, 225 {9.3750, 5894.95873086734181634245918412592155656}, 226 {9.4375, 6275.15090986233399457103055108344546942}, 227 {9.5000, 6679.86337740502119410058225086262108741}, 228 {9.5625, 7110.67755625726876329967852256934334025}, 229 {9.6250, 7569.27686218510919585241049433331592115}, 230 {9.6875, 8057.45328194243077504648484392156371121}, 231 {9.7500, 8577.11437549816065709098061006273039092}, 232 {9.8125, 9130.29072986829727910801024120918114778}, 233 {9.8750, 9719.14389367880274015504995181862860062}, 234 {9.9375, 10345.97482346383208590278839409938269134}, 235 {10.0000, 11013.23287470339337723652455484636420303}, 236 }; 237 238 for (double[] testCase : testCases) { 239 testSinhCaseWithUlpDiff(testCase[0], testCase[1], 3.0); 240 } 241 242 double[][] specialTestCases = { 243 {0.0, 0.0}, 244 {NaNd, NaNd}, 245 {Double.longBitsToDouble(0x7FF0000000000001L), NaNd}, 246 {Double.longBitsToDouble(0xFFF0000000000001L), NaNd}, 247 {Double.longBitsToDouble(0x7FF8555555555555L), NaNd}, 248 {Double.longBitsToDouble(0xFFF8555555555555L), NaNd}, 249 {Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL), NaNd}, 250 {Double.longBitsToDouble(0xFFFFFFFFFFFFFFFFL), NaNd}, 251 {Double.longBitsToDouble(0x7FFDeadBeef00000L), NaNd}, 252 {Double.longBitsToDouble(0xFFFDeadBeef00000L), NaNd}, 253 {Double.longBitsToDouble(0x7FFCafeBabe00000L), NaNd}, 254 {Double.longBitsToDouble(0xFFFCafeBabe00000L), NaNd}, 255 {Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY} 256 }; 257 258 for (double[] specialTestCase : specialTestCases) { 259 testSinhCaseWithUlpDiff(specialTestCase[0], specialTestCase[1], 0.0); 260 } 261 262 // For powers of 2 less than 2^(-27), the second and 263 // subsequent terms of the Taylor series expansion will get 264 // rounded away since |n-n^3| > 53, the binary precision of a 265 // double significand. 266 267 for (int i = DoubleConsts.MIN_SUB_EXPONENT; i < -27; i++) { 268 double d = Math.scalb(2.0, i); 269 270 // Result and expected are the same. 271 testSinhCaseWithUlpDiff(d, d, 2.5); 272 } 273 274 // For values of x larger than 22, the e^(-x) term is 275 // insignificant to the floating-point result. Util exp(x) 276 // overflows around 709.8, sinh(x) ~= exp(x)/2; will will test 277 // 10000 values in this range. 278 279 long trans22 = Double.doubleToLongBits(22.0); 280 // (approximately) largest value such that exp shouldn't 281 // overflow 282 long transExpOvfl = Double.doubleToLongBits(Math.nextDown(709.7827128933841)); 283 284 for (long i = trans22; 285 i < transExpOvfl; 286 i += (transExpOvfl - trans22) / 10000) { 287 288 double d = Double.longBitsToDouble(i); 289 290 // Allow 3.5 ulps of error to deal with error in exp. 291 testSinhCaseWithUlpDiff(d, StrictMath.exp(d) * 0.5, 3.5); 292 } 293 294 // (approximately) largest value such that sinh shouldn't 295 // overflow. 296 long transSinhOvfl = Double.doubleToLongBits(710.4758600739439); 297 298 // Make sure sinh(x) doesn't overflow as soon as exp(x) 299 // overflows. 300 301 /* 302 * For large values of x, sinh(x) ~= 0.5*(e^x). Therefore, 303 * 304 * sinh(x) ~= e^(ln 0.5) * e^x = e^(x + ln 0.5) 305 * 306 * So, we can calculate the approximate expected result as 307 * exp(x + -0.693147186). However, this sum suffers from 308 * roundoff, limiting the accuracy of the approximation. The 309 * accuracy can be improved by recovering the rounded-off 310 * information. Since x is larger than ln(0.5), the trailing 311 * bits of ln(0.5) get rounded away when the two values are 312 * added. However, high-order bits of ln(0.5) that 313 * contribute to the sum can be found: 314 * 315 * offset = log(0.5); 316 * effective_offset = (x + offset) - x; // exact subtraction 317 * rounded_away_offset = offset - effective_offset; // exact subtraction 318 * 319 * Therefore, the product 320 * 321 * exp(x + offset)*exp(rounded_away_offset) 322 * 323 * will be a better approximation to the exact value of 324 * 325 * e^(x + offset) 326 * 327 * than exp(x+offset) alone. (The expected result cannot be 328 * computed as exp(x)*exp(offset) since exp(x) by itself would 329 * overflow to infinity.) 330 */ 331 double offset = StrictMath.log(0.5); 332 for (long i = transExpOvfl + 1; i < transSinhOvfl; 333 i += (transSinhOvfl - transExpOvfl) / 1000) { 334 double input = Double.longBitsToDouble(i); 335 336 double expected = 337 StrictMath.exp(input + offset) * 338 StrictMath.exp(offset - ((input + offset) - input)); 339 340 testSinhCaseWithUlpDiff(input, expected, 4.0); 341 } 342 343 // sinh(x) overflows for values greater than 710; in 344 // particular, it overflows for all 2^i, i > 10. 345 for (int i = 10; i <= Double.MAX_EXPONENT; i++) { 346 double d = Math.scalb(2.0, i); 347 348 // Result and expected are the same. 349 testSinhCaseWithUlpDiff(d, Double.POSITIVE_INFINITY, 0.0); 350 } 351 } 352 testSinhCaseWithTolerance(double input, double expected, double tolerance)353 public static int testSinhCaseWithTolerance(double input, 354 double expected, 355 double tolerance) { 356 int failures = 0; 357 Tests.testTolerance("Math.sinh(double)", 358 input, Math.sinh(input), 359 expected, tolerance); 360 Tests.testTolerance("Math.sinh(double)", 361 -input, Math.sinh(-input), 362 -expected, tolerance); 363 364 Tests.testTolerance("StrictMath.sinh(double)", 365 input, StrictMath.sinh(input), 366 expected, tolerance); 367 Tests.testTolerance("StrictMath.sinh(double)", 368 -input, StrictMath.sinh(-input), 369 -expected, tolerance); 370 return failures; 371 } 372 testSinhCaseWithUlpDiff(double input, double expected, double ulps)373 public static void testSinhCaseWithUlpDiff(double input, 374 double expected, 375 double ulps) { 376 int failures = 0; 377 Tests.testUlpDiff("Math.sinh(double)", 378 input, Math.sinh(input), 379 expected, ulps); 380 Tests.testUlpDiff("Math.sinh(double)", 381 -input, Math.sinh(-input), 382 -expected, ulps); 383 384 Tests.testUlpDiff("StrictMath.sinh(double)", 385 input, StrictMath.sinh(input), 386 expected, ulps); 387 Tests.testUlpDiff("StrictMath.sinh(double)", 388 -input, StrictMath.sinh(-input), 389 -expected, ulps); 390 } 391 392 393 /** 394 * Test accuracy of {Math, StrictMath}.cosh. The specified accuracy is 2.5 ulps. 395 * 396 * The definition of cosh(x) is 397 * 398 * (e^x + e^(-x))/2 399 * 400 * The series expansion of cosh(x) = 401 * 402 * 1 + x^2/2! + x^4/4! + x^6/6! +... 403 * 404 * Therefore, 405 * 406 * 1. For large values of x cosh(x) ~= exp(|x|)/2 407 * 408 * 2. For small values of x, cosh(x) ~= 1. 409 * 410 * Additionally, cosh is an even function; cosh(-x) = cosh(x). 411 */ 412 @LargeTest 413 @Test testCosh()414 public void testCosh() { 415 /* 416 * Array elements below generated using a quad cosh 417 * implementation. Rounded to a double, the quad result 418 * *should* be correctly rounded, unless we are quite unlucky. 419 * Assuming the quad value is a correctly rounded double, the 420 * allowed error is 3.0 ulps instead of 2.5 since the quad 421 * value rounded to double can have its own 1/2 ulp error. 422 */ 423 double[][] testCases = { 424 // x cosh(x) 425 {0.0625, 1.001953760865667607841550709632597376}, 426 {0.1250, 1.007822677825710859846949685520422223}, 427 {0.1875, 1.017629683800690526835115759894757615}, 428 {0.2500, 1.031413099879573176159295417520378622}, 429 {0.3125, 1.049226785060219076999158096606305793}, 430 {0.3750, 1.071140346704586767299498015567016002}, 431 {0.4375, 1.097239412531012567673453832328262160}, 432 {0.5000, 1.127625965206380785226225161402672030}, 433 {0.5625, 1.162418740845610783505338363214045218}, 434 {0.6250, 1.201753692975606324229229064105075301}, 435 {0.6875, 1.245784523776616395403056980542275175}, 436 {0.7500, 1.294683284676844687841708185390181730}, 437 {0.8125, 1.348641048647144208352285714214372703}, 438 {0.8750, 1.407868656822803158638471458026344506}, 439 {0.9375, 1.472597542369862933336886403008640891}, 440 {1.0000, 1.543080634815243778477905620757061497}, 441 {1.0625, 1.619593348374367728682469968448090763}, 442 {1.1250, 1.702434658138190487400868008124755757}, 443 {1.1875, 1.791928268324866464246665745956119612}, 444 {1.2500, 1.888423877161015738227715728160051696}, 445 {1.3125, 1.992298543335143985091891077551921106}, 446 {1.3750, 2.103958159362661802010972984204389619}, 447 {1.4375, 2.223839037619709260803023946704272699}, 448 {1.5000, 2.352409615243247325767667965441644201}, 449 {1.5625, 2.490172284559350293104864895029231913}, 450 {1.6250, 2.637665356192137582275019088061812951}, 451 {1.6875, 2.795465162524235691253423614360562624}, 452 {1.7500, 2.964188309728087781773608481754531801}, 453 {1.8125, 3.144494087167972176411236052303565201}, 454 {1.8750, 3.337087043587520514308832278928116525}, 455 {1.9375, 3.542719740149244276729383650503145346}, 456 {2.0000, 3.762195691083631459562213477773746099}, 457 {2.0625, 3.996372503438463642260225717607554880}, 458 {2.1250, 4.246165228196992140600291052990934410}, 459 {2.1875, 4.512549935859540340856119781585096760}, 460 {2.2500, 4.796567530460195028666793366876218854}, 461 {2.3125, 5.099327816921939817643745917141739051}, 462 {2.3750, 5.422013837643509250646323138888569746}, 463 {2.4375, 5.765886495263270945949271410819116399}, 464 {2.5000, 6.132289479663686116619852312817562517}, 465 {2.5625, 6.522654518468725462969589397439224177}, 466 {2.6250, 6.938506971550673190999796241172117288}, 467 {2.6875, 7.381471791406976069645686221095397137}, 468 {2.7500, 7.853279872697439591457564035857305647}, 469 {2.8125, 8.355774815752725814638234943192709129}, 470 {2.8750, 8.890920130482709321824793617157134961}, 471 {2.9375, 9.460806908834119747071078865866737196}, 472 {3.0000, 10.067661995777765841953936035115890343}, 473 {3.0625, 10.713856690753651225304006562698007312}, 474 {3.1250, 11.401916013575067700373788969458446177}, 475 {3.1875, 12.134528570998387744547733730974713055}, 476 {3.2500, 12.914557062512392049483503752322408761}, 477 {3.3125, 13.745049466398732213877084541992751273}, 478 {3.3750, 14.629250949773302934853381428660210721}, 479 {3.4375, 15.570616549147269180921654324879141947}, 480 {3.5000, 16.572824671057316125696517821376119469}, 481 {3.5625, 17.639791465519127930722105721028711044}, 482 {3.6250, 18.775686128468677200079039891415789429}, 483 {3.6875, 19.984947192985946987799359614758598457}, 484 {3.7500, 21.272299872959396081877161903352144126}, 485 {3.8125, 22.642774526961913363958587775566619798}, 486 {3.8750, 24.101726314486257781049388094955970560}, 487 {3.9375, 25.654856121347151067170940701379544221}, 488 {4.0000, 27.308232836016486629201989612067059978}, 489 {4.0625, 29.068317063936918520135334110824828950}, 490 {4.1250, 30.941986372478026192360480044849306606}, 491 {4.1875, 32.936562165180269851350626768308756303}, 492 {4.2500, 35.059838290298428678502583470475012235}, 493 {4.3125, 37.320111495433027109832850313172338419}, 494 {4.3750, 39.726213847251883288518263854094284091}, 495 {4.4375, 42.287547242982546165696077854963452084}, 496 {4.5000, 45.014120148530027928305799939930642658}, 497 {4.5625, 47.916586706774825161786212701923307169}, 498 {4.6250, 51.006288368867753140854830589583165950}, 499 {4.6875, 54.295298211196782516984520211780624960}, 500 {4.7500, 57.796468111195389383795669320243166117}, 501 {4.8125, 61.523478966332915041549750463563672435}, 502 {4.8750, 65.490894152518731617237739112888213645}, 503 {4.9375, 69.714216430810089539924900313140922323}, 504 {5.0000, 74.209948524787844444106108044487704798}, 505 {5.0625, 78.995657605307475581204965926043112946}, 506 {5.1250, 84.090043934600961683400343038519519678}, 507 {5.1875, 89.513013937957834087706670952561002466}, 508 {5.2500, 95.285757988514588780586084642381131013}, 509 {5.3125, 101.430833209098212357990123684449846912}, 510 {5.3750, 107.972251614673824873137995865940755392}, 511 {5.4375, 114.935573939814969189535554289886848550}, 512 {5.5000, 122.348009517829425991091207107262038316}, 513 {5.5625, 130.238522601820409078244923165746295574}, 514 {5.6250, 138.637945543134998069351279801575968875}, 515 {5.6875, 147.579099269447055276899288971207106581}, 516 {5.7500, 157.096921533245353905868840194264636395}, 517 {5.8125, 167.228603431860671946045256541679445836}, 518 {5.8750, 178.013734732486824390148614309727161925}, 519 {5.9375, 189.494458570056311567917444025807275896}, 520 {6.0000, 201.715636122455894483405112855409538488}, 521 {6.0625, 214.725021906554080628430756558271312513}, 522 {6.1250, 228.573450380013557089736092321068279231}, 523 {6.1875, 243.315034578039208138752165587134488645}, 524 {6.2500, 259.007377561239126824465367865430519592}, 525 {6.3125, 275.711797500835732516530131577254654076}, 526 {6.3750, 293.493567280752348242602902925987643443}, 527 {6.4375, 312.422169552825597994104814531010579387}, 528 {6.5000, 332.571568241777409133204438572983297292}, 529 {6.5625, 354.020497560858198165985214519757890505}, 530 {6.6250, 376.852769667496146326030849450983914197}, 531 {6.6875, 401.157602161123700280816957271992998156}, 532 {6.7500, 427.029966702886171977469256622451185850}, 533 {6.8125, 454.570960119471524953536004647195906721}, 534 {6.8750, 483.888199441157626584508920036981010995}, 535 {6.9375, 515.096242417696720610477570797503766179}, 536 {7.0000, 548.317035155212076889964120712102928484}, 537 {7.0625, 583.680388623257719787307547662358502345}, 538 {7.1250, 621.324485894002926216918634755431456031}, 539 {7.1875, 661.396422095589629755266517362992812037}, 540 {7.2500, 704.052779189542208784574955807004218856}, 541 {7.3125, 749.460237818184878095966335081928645934}, 542 {7.3750, 797.796228612873763671070863694973560629}, 543 {7.4375, 849.249625508044731271830060572510241864}, 544 {7.5000, 904.021483770216677368692292389446994987}, 545 {7.5625, 962.325825625814651122171697031114091993}, 546 {7.6250, 1024.390476557670599008492465853663578558}, 547 {7.6875, 1090.457955538048482588540574008226583335}, 548 {7.7500, 1160.786422676798661020094043586456606003}, 549 {7.8125, 1235.650687987597295222707689125107720568}, 550 {7.8750, 1315.343285214046776004329388551335841550}, 551 {7.9375, 1400.175614911635999247504386054087931958}, 552 {8.0000, 1490.479161252178088627715460421007179728}, 553 {8.0625, 1586.606787305415349050508956232945539108}, 554 {8.1250, 1688.934113859132470361718199038326340668}, 555 {8.1875, 1797.860987165547537276364148450577336075}, 556 {8.2500, 1913.813041349231764486365114317586148767}, 557 {8.3125, 2037.243361581700856522236313401822532385}, 558 {8.3750, 2168.634254521568851112005905503069409349}, 559 {8.4375, 2308.499132938297821208734949028296170563}, 560 {8.5000, 2457.384521883751693037774022640629666294}, 561 {8.5625, 2615.872194250713123494312356053193077854}, 562 {8.6250, 2784.581444063104750127653362960649823247}, 563 {8.6875, 2964.171506380845754878370650565756538203}, 564 {8.7500, 3155.344133275174556354775488913749659006}, 565 {8.8125, 3358.846335940117183452010789979584950102}, 566 {8.8750, 3575.473303654961482727206202358956274888}, 567 {8.9375, 3806.071511003646460448021740303914939059}, 568 {9.0000, 4051.542025492594047194773093534725371440}, 569 {9.0625, 4312.844028491571841588188869958240355518}, 570 {9.1250, 4590.998563255739769060078863130940205710}, 571 {9.1875, 4887.092524674358252509551443117048351290}, 572 {9.2500, 5202.282906336187674588222835339193136030}, 573 {9.3125, 5537.801321507079474415176386655744387251}, 574 {9.3750, 5894.958815685577062811620236195525504885}, 575 {9.4375, 6275.150989541692149890530417987358096221}, 576 {9.5000, 6679.863452256851081801173722051940058824}, 577 {9.5625, 7110.677626574055535297758456126491707647}, 578 {9.6250, 7569.276928241617224537226019600213961572}, 579 {9.6875, 8057.453343996777301036241026375049070162}, 580 {9.7500, 8577.114433792824387959788368429252257664}, 581 {9.8125, 9130.290784631065880205118262838330689429}, 582 {9.8750, 9719.143945123662919857326995631317996715}, 583 {9.9375, 10345.974871791805753327922796701684092861}, 584 {10.0000, 11013.232920103323139721376090437880844591}, 585 }; 586 587 for (double[] testCase : testCases) { 588 testCoshCaseWithUlpDiff(testCase[0], testCase[1], 3.0); 589 } 590 591 double[][] specialTestCases = { 592 {0.0, 1.0}, 593 {NaNd, NaNd}, 594 {Double.longBitsToDouble(0x7FF0000000000001L), NaNd}, 595 {Double.longBitsToDouble(0xFFF0000000000001L), NaNd}, 596 {Double.longBitsToDouble(0x7FF8555555555555L), NaNd}, 597 {Double.longBitsToDouble(0xFFF8555555555555L), NaNd}, 598 {Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL), NaNd}, 599 {Double.longBitsToDouble(0xFFFFFFFFFFFFFFFFL), NaNd}, 600 {Double.longBitsToDouble(0x7FFDeadBeef00000L), NaNd}, 601 {Double.longBitsToDouble(0xFFFDeadBeef00000L), NaNd}, 602 {Double.longBitsToDouble(0x7FFCafeBabe00000L), NaNd}, 603 {Double.longBitsToDouble(0xFFFCafeBabe00000L), NaNd}, 604 {Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY} 605 }; 606 607 for (double[] specialTestCase : specialTestCases) { 608 testCoshCaseWithUlpDiff(specialTestCase[0], specialTestCase[1], 0.0); 609 } 610 611 // For powers of 2 less than 2^(-27), the second and 612 // subsequent terms of the Taylor series expansion will get 613 // rounded. 614 615 for (int i = DoubleConsts.MIN_SUB_EXPONENT; i < -27; i++) { 616 double d = Math.scalb(2.0, i); 617 618 // Result and expected are the same. 619 testCoshCaseWithUlpDiff(d, 1.0, 2.5); 620 } 621 622 // For values of x larger than 22, the e^(-x) term is 623 // insignificant to the floating-point result. Util exp(x) 624 // overflows around 709.8, cosh(x) ~= exp(x)/2; will will test 625 // 10000 values in this range. 626 627 long trans22 = Double.doubleToLongBits(22.0); 628 // (approximately) largest value such that exp shouldn't 629 // overflow 630 long transExpOvfl = Double.doubleToLongBits(Math.nextDown(709.7827128933841)); 631 632 for (long i = trans22; 633 i < transExpOvfl; 634 i += (transExpOvfl - trans22) / 10000) { 635 636 double d = Double.longBitsToDouble(i); 637 638 // Allow 3.5 ulps of error to deal with error in exp. 639 testCoshCaseWithUlpDiff(d, StrictMath.exp(d) * 0.5, 3.5); 640 } 641 642 // (approximately) largest value such that cosh shouldn't 643 // overflow. 644 long transCoshOvfl = Double.doubleToLongBits(710.4758600739439); 645 646 // Make sure sinh(x) doesn't overflow as soon as exp(x) 647 // overflows. 648 649 /* 650 * For large values of x, cosh(x) ~= 0.5*(e^x). Therefore, 651 * 652 * cosh(x) ~= e^(ln 0.5) * e^x = e^(x + ln 0.5) 653 * 654 * So, we can calculate the approximate expected result as 655 * exp(x + -0.693147186). However, this sum suffers from 656 * roundoff, limiting the accuracy of the approximation. The 657 * accuracy can be improved by recovering the rounded-off 658 * information. Since x is larger than ln(0.5), the trailing 659 * bits of ln(0.5) get rounded away when the two values are 660 * added. However, high-order bits of ln(0.5) that 661 * contribute to the sum can be found: 662 * 663 * offset = log(0.5); 664 * effective_offset = (x + offset) - x; // exact subtraction 665 * rounded_away_offset = offset - effective_offset; // exact subtraction 666 * 667 * Therefore, the product 668 * 669 * exp(x + offset)*exp(rounded_away_offset) 670 * 671 * will be a better approximation to the exact value of 672 * 673 * e^(x + offset) 674 * 675 * than exp(x+offset) alone. (The expected result cannot be 676 * computed as exp(x)*exp(offset) since exp(x) by itself would 677 * overflow to infinity.) 678 */ 679 double offset = StrictMath.log(0.5); 680 for (long i = transExpOvfl + 1; i < transCoshOvfl; 681 i += (transCoshOvfl - transExpOvfl) / 1000) { 682 double input = Double.longBitsToDouble(i); 683 684 double expected = 685 StrictMath.exp(input + offset) * 686 StrictMath.exp(offset - ((input + offset) - input)); 687 688 testCoshCaseWithUlpDiff(input, expected, 4.0); 689 } 690 691 // cosh(x) overflows for values greater than 710; in 692 // particular, it overflows for all 2^i, i > 10. 693 for (int i = 10; i <= Double.MAX_EXPONENT; i++) { 694 double d = Math.scalb(2.0, i); 695 696 // Result and expected are the same. 697 testCoshCaseWithUlpDiff(d, Double.POSITIVE_INFINITY, 0.0); 698 } 699 } 700 testCoshCaseWithTolerance(double input, double expected, double tolerance)701 public static int testCoshCaseWithTolerance(double input, 702 double expected, 703 double tolerance) { 704 int failures = 0; 705 Tests.testTolerance("Math.cosh(double)", 706 input, Math.cosh(input), 707 expected, tolerance); 708 Tests.testTolerance("Math.cosh(double)", 709 -input, Math.cosh(-input), 710 expected, tolerance); 711 712 Tests.testTolerance("StrictMath.cosh(double)", 713 input, StrictMath.cosh(input), 714 expected, tolerance); 715 Tests.testTolerance("StrictMath.cosh(double)", 716 -input, StrictMath.cosh(-input), 717 expected, tolerance); 718 return failures; 719 } 720 testCoshCaseWithUlpDiff(double input, double expected, double ulps)721 public static void testCoshCaseWithUlpDiff(double input, 722 double expected, 723 double ulps) { 724 int failures = 0; 725 Tests.testUlpDiff("Math.cosh(double)", 726 input, Math.cosh(input), 727 expected, ulps); 728 Tests.testUlpDiff("Math.cosh(double)", 729 -input, Math.cosh(-input), 730 expected, ulps); 731 732 Tests.testUlpDiff("StrictMath.cosh(double)", 733 input, StrictMath.cosh(input), 734 expected, ulps); 735 Tests.testUlpDiff("StrictMath.cosh(double)", 736 -input, StrictMath.cosh(-input), 737 expected, ulps); 738 } 739 740 741 /** 742 * Test accuracy of {Math, StrictMath}.tanh. The specified accuracy is 2.5 ulps. 743 * 744 * The definition of tanh(x) is 745 * 746 * (e^x - e^(-x))/(e^x + e^(-x)) 747 * 748 * The series expansion of tanh(x) = 749 * 750 * x - x^3/3 + 2x^5/15 - 17x^7/315 + ... 751 * 752 * Therefore, 753 * 754 * 1. For large values of x tanh(x) ~= signum(x) 755 * 756 * 2. For small values of x, tanh(x) ~= x. 757 * 758 * Additionally, tanh is an odd function; tanh(-x) = -tanh(x). 759 */ 760 @Test testTanh()761 public void testTanh() { 762 /* 763 * Array elements below generated using a quad sinh 764 * implementation. Rounded to a double, the quad result 765 * *should* be correctly rounded, unless we are quite unlucky. 766 * Assuming the quad value is a correctly rounded double, the 767 * allowed error is 3.0 ulps instead of 2.5 since the quad 768 * value rounded to double can have its own 1/2 ulp error. 769 */ 770 double[][] testCases = { 771 // x tanh(x) 772 {0.0625, 0.06241874674751251449014289119421133}, 773 {0.1250, 0.12435300177159620805464727580589271}, 774 {0.1875, 0.18533319990813951753211997502482787}, 775 {0.2500, 0.24491866240370912927780113149101697}, 776 {0.3125, 0.30270972933210848724239738970991712}, 777 {0.3750, 0.35835739835078594631936023155315807}, 778 {0.4375, 0.41157005567402245143207555859415687}, 779 {0.5000, 0.46211715726000975850231848364367256}, 780 {0.5625, 0.50982997373525658248931213507053130}, 781 {0.6250, 0.55459972234938229399903909532308371}, 782 {0.6875, 0.59637355547924233984437303950726939}, 783 {0.7500, 0.63514895238728731921443435731249638}, 784 {0.8125, 0.67096707420687367394810954721913358}, 785 {0.8750, 0.70390560393662106058763026963135371}, 786 {0.9375, 0.73407151960434149263991588052503660}, 787 {1.0000, 0.76159415595576488811945828260479366}, 788 {1.0625, 0.78661881210869761781941794647736081}, 789 {1.1250, 0.80930107020178101206077047354332696}, 790 {1.1875, 0.82980190998595952708572559629034476}, 791 {1.2500, 0.84828363995751289761338764670750445}, 792 {1.3125, 0.86490661772074179125443141102709751}, 793 {1.3750, 0.87982669965198475596055310881018259}, 794 {1.4375, 0.89319334040035153149249598745889365}, 795 {1.5000, 0.90514825364486643824230369645649557}, 796 {1.5625, 0.91582454416876231820084311814416443}, 797 {1.6250, 0.92534622531174107960457166792300374}, 798 {1.6875, 0.93382804322259173763570528576138652}, 799 {1.7500, 0.94137553849728736226942088377163687}, 800 {1.8125, 0.94808528560440629971240651310180052}, 801 {1.8750, 0.95404526017994877009219222661968285}, 802 {1.9375, 0.95933529331468249183399461756952555}, 803 {2.0000, 0.96402758007581688394641372410092317}, 804 {2.0625, 0.96818721657637057702714316097855370}, 805 {2.1250, 0.97187274591350905151254495374870401}, 806 {2.1875, 0.97513669829362836159665586901156483}, 807 {2.2500, 0.97802611473881363992272924300618321}, 808 {2.3125, 0.98058304703705186541999427134482061}, 809 {2.3750, 0.98284502917257603002353801620158861}, 810 {2.4375, 0.98484551746427837912703608465407824}, 811 {2.5000, 0.98661429815143028888127603923734964}, 812 {2.5625, 0.98817786228751240824802592958012269}, 813 {2.6250, 0.98955974861288320579361709496051109}, 814 {2.6875, 0.99078085564125158320311117560719312}, 815 {2.7500, 0.99185972456820774534967078914285035}, 816 {2.8125, 0.99281279483715982021711715899682324}, 817 {2.8750, 0.99365463431502962099607366282699651}, 818 {2.9375, 0.99439814606575805343721743822723671}, 819 {3.0000, 0.99505475368673045133188018525548849}, 820 {3.0625, 0.99563456710930963835715538507891736}, 821 {3.1250, 0.99614653067334504917102591131792951}, 822 {3.1875, 0.99659855517712942451966113109487039}, 823 {3.2500, 0.99699763548652601693227592643957226}, 824 {3.3125, 0.99734995516557367804571991063376923}, 825 {3.3750, 0.99766097946988897037219469409451602}, 826 {3.4375, 0.99793553792649036103161966894686844}, 827 {3.5000, 0.99817789761119870928427335245061171}, 828 {3.5625, 0.99839182812874152902001617480606320}, 829 {3.6250, 0.99858065920179882368897879066418294}, 830 {3.6875, 0.99874733168378115962760304582965538}, 831 {3.7500, 0.99889444272615280096784208280487888}, 832 {3.8125, 0.99902428575443546808677966295308778}, 833 {3.8750, 0.99913888583735077016137617231569011}, 834 {3.9375, 0.99924003097049627100651907919688313}, 835 {4.0000, 0.99932929973906704379224334434172499}, 836 {4.0625, 0.99940808577297384603818654530731215}, 837 {4.1250, 0.99947761936180856115470576756499454}, 838 {4.1875, 0.99953898655601372055527046497863955}, 839 {4.2500, 0.99959314604388958696521068958989891}, 840 {4.3125, 0.99964094406130644525586201091350343}, 841 {4.3750, 0.99968312756179494813069349082306235}, 842 {4.4375, 0.99972035584870534179601447812936151}, 843 {4.5000, 0.99975321084802753654050617379050162}, 844 {4.5625, 0.99978220617994689112771768489030236}, 845 {4.6250, 0.99980779516900105210240981251048167}, 846 {4.6875, 0.99983037791655283849546303868853396}, 847 {4.7500, 0.99985030754497877753787358852000255}, 848 {4.8125, 0.99986789571029070417475400133989992}, 849 {4.8750, 0.99988341746867772271011794614780441}, 850 {4.9375, 0.99989711557251558205051185882773206}, 851 {5.0000, 0.99990920426259513121099044753447306}, 852 {5.0625, 0.99991987261554158551063867262784721}, 853 {5.1250, 0.99992928749851651137225712249720606}, 854 {5.1875, 0.99993759617721206697530526661105307}, 855 {5.2500, 0.99994492861777083305830639416802036}, 856 {5.3125, 0.99995139951851344080105352145538345}, 857 {5.3750, 0.99995711010315817210152906092289064}, 858 {5.4375, 0.99996214970350792531554669737676253}, 859 {5.5000, 0.99996659715630380963848952941756868}, 860 {5.5625, 0.99997052203605101013786592945475432}, 861 {5.6250, 0.99997398574306704793434088941484766}, 862 {5.6875, 0.99997704246374583929961850444364696}, 863 {5.7500, 0.99997974001803825215761760428815437}, 864 {5.8125, 0.99998212060739040166557477723121777}, 865 {5.8750, 0.99998422147482750993344503195672517}, 866 {5.9375, 0.99998607548749972326220227464612338}, 867 {6.0000, 0.99998771165079557056434885235523206}, 868 {6.0625, 0.99998915556205996764518917496149338}, 869 {6.1250, 0.99999042981101021976277974520745310}, 870 {6.1875, 0.99999155433311068015449574811497719}, 871 {6.2500, 0.99999254672143162687722782398104276}, 872 {6.3125, 0.99999342250186907900400800240980139}, 873 {6.3750, 0.99999419537602957780612639767025158}, 874 {6.4375, 0.99999487743557848265406225515388994}, 875 {6.5000, 0.99999547935140419285107893831698753}, 876 {6.5625, 0.99999601054055694588617385671796346}, 877 {6.6250, 0.99999647931357331502887600387959900}, 878 {6.6875, 0.99999689300449080997594368612277442}, 879 {6.7500, 0.99999725808558628431084200832778748}, 880 {6.8125, 0.99999758026863294516387464046135924}, 881 {6.8750, 0.99999786459425991170635407313276785}, 882 {6.9375, 0.99999811551081218572759991597586905}, 883 {7.0000, 0.99999833694394467173571641595066708}, 884 {7.0625, 0.99999853235803894918375164252059190}, 885 {7.1250, 0.99999870481040359014665019356422927}, 886 {7.1875, 0.99999885699910593255108365463415411}, 887 {7.2500, 0.99999899130518359709674536482047025}, 888 {7.3125, 0.99999910982989611769943303422227663}, 889 {7.3750, 0.99999921442759946591163427422888252}, 890 {7.4375, 0.99999930673475777603853435094943258}, 891 {7.5000, 0.99999938819554614875054970643513124}, 892 {7.5625, 0.99999946008444508183970109263856958}, 893 {7.6250, 0.99999952352618001331402589096040117}, 894 {7.6875, 0.99999957951331792817413683491979752}, 895 {7.7500, 0.99999962892179632633374697389145081}, 896 {7.8125, 0.99999967252462750190604116210421169}, 897 {7.8750, 0.99999971100399253750324718031574484}, 898 {7.9375, 0.99999974496191422474977283863588658}, 899 {8.0000, 0.99999977492967588981001883295636840}, 900 {8.0625, 0.99999980137613348259726597081723424}, 901 {8.1250, 0.99999982471505097353529823063673263}, 902 {8.1875, 0.99999984531157382142423402736529911}, 903 {8.2500, 0.99999986348794179107425910499030547}, 904 {8.3125, 0.99999987952853049895833839645847571}, 905 {8.3750, 0.99999989368430056302584289932834041}, 906 {8.4375, 0.99999990617672396471542088609051728}, 907 {8.5000, 0.99999991720124905211338798152800748}, 908 {8.5625, 0.99999992693035839516545287745322387}, 909 {8.6250, 0.99999993551626733394129009365703767}, 910 {8.6875, 0.99999994309330543951799157347876934}, 911 {8.7500, 0.99999994978001814614368429416607424}, 912 {8.8125, 0.99999995568102143535399207289008504}, 913 {8.8750, 0.99999996088863858914831986187674522}, 914 {8.9375, 0.99999996548434461974481685677429908}, 915 {9.0000, 0.99999996954004097447930211118358244}, 916 {9.0625, 0.99999997311918045901919121395899372}, 917 {9.1250, 0.99999997627775997868467948564005257}, 918 {9.1875, 0.99999997906519662964368381583648379}, 919 {9.2500, 0.99999998152510084671976114264303159}, 920 {9.3125, 0.99999998369595870397054673668361266}, 921 {9.3750, 0.99999998561173404286033236040150950}, 922 {9.4375, 0.99999998730239984852716512979473289}, 923 {9.5000, 0.99999998879440718770812040917618843}, 924 {9.5625, 0.99999999011109904501789298212541698}, 925 {9.6250, 0.99999999127307553219220251303121960}, 926 {9.6875, 0.99999999229851618412119275358396363}, 927 {9.7500, 0.99999999320346438410630581726217930}, 928 {9.8125, 0.99999999400207836827291739324060736}, 929 {9.8750, 0.99999999470685273619047001387577653}, 930 {9.9375, 0.99999999532881393331131526966058758}, 931 {10.0000, 0.99999999587769276361959283713827574}, 932 }; 933 934 for (double[] testCase : testCases) { 935 testTanhCaseWithUlpDiff(testCase[0], testCase[1], 3.0); 936 } 937 938 double[][] specialTestCases = { 939 {0.0, 0.0}, 940 {NaNd, NaNd}, 941 {Double.longBitsToDouble(0x7FF0000000000001L), NaNd}, 942 {Double.longBitsToDouble(0xFFF0000000000001L), NaNd}, 943 {Double.longBitsToDouble(0x7FF8555555555555L), NaNd}, 944 {Double.longBitsToDouble(0xFFF8555555555555L), NaNd}, 945 {Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL), NaNd}, 946 {Double.longBitsToDouble(0xFFFFFFFFFFFFFFFFL), NaNd}, 947 {Double.longBitsToDouble(0x7FFDeadBeef00000L), NaNd}, 948 {Double.longBitsToDouble(0xFFFDeadBeef00000L), NaNd}, 949 {Double.longBitsToDouble(0x7FFCafeBabe00000L), NaNd}, 950 {Double.longBitsToDouble(0xFFFCafeBabe00000L), NaNd}, 951 {Double.POSITIVE_INFINITY, 1.0} 952 }; 953 954 for (double[] specialTestCase : specialTestCases) { 955 testTanhCaseWithUlpDiff(specialTestCase[0], specialTestCase[1], 0.0); 956 } 957 958 // For powers of 2 less than 2^(-27), the second and 959 // subsequent terms of the Taylor series expansion will get 960 // rounded away since |n-n^3| > 53, the binary precision of a 961 // double significand. 962 963 for (int i = DoubleConsts.MIN_SUB_EXPONENT; i < -27; i++) { 964 double d = Math.scalb(2.0, i); 965 966 // Result and expected are the same. 967 testTanhCaseWithUlpDiff(d, d, 2.5); 968 } 969 970 // For values of x larger than 22, tanh(x) is 1.0 in double 971 // floating-point arithmetic. 972 973 for (int i = 22; i < 32; i++) { 974 testTanhCaseWithUlpDiff(i, 1.0, 2.5); 975 } 976 977 for (int i = 5; i <= Double.MAX_EXPONENT; i++) { 978 double d = Math.scalb(2.0, i); 979 980 testTanhCaseWithUlpDiff(d, 1.0, 2.5); 981 } 982 } 983 testTanhCaseWithTolerance(double input, double expected, double tolerance)984 public static int testTanhCaseWithTolerance(double input, 985 double expected, 986 double tolerance) { 987 int failures = 0; 988 Tests.testTolerance("Math.tanh(double", 989 input, Math.tanh(input), 990 expected, tolerance); 991 Tests.testTolerance("Math.tanh(double", 992 -input, Math.tanh(-input), 993 -expected, tolerance); 994 995 Tests.testTolerance("StrictMath.tanh(double", 996 input, StrictMath.tanh(input), 997 expected, tolerance); 998 Tests.testTolerance("StrictMath.tanh(double", 999 -input, StrictMath.tanh(-input), 1000 -expected, tolerance); 1001 return failures; 1002 } 1003 testTanhCaseWithUlpDiff(double input, double expected, double ulps)1004 public static void testTanhCaseWithUlpDiff(double input, 1005 double expected, 1006 double ulps) { 1007 Tests.testUlpDiffWithAbsBound("Math.tanh(double)", 1008 input, Math.tanh(input), 1009 expected, ulps, 1.0); 1010 Tests.testUlpDiffWithAbsBound("Math.tanh(double)", 1011 -input, Math.tanh(-input), 1012 -expected, ulps, 1.0); 1013 1014 Tests.testUlpDiffWithAbsBound("StrictMath.tanh(double)", 1015 input, StrictMath.tanh(input), 1016 expected, ulps, 1.0); 1017 Tests.testUlpDiffWithAbsBound("StrictMath.tanh(double)", 1018 -input, StrictMath.tanh(-input), 1019 -expected, ulps, 1.0); 1020 } 1021 } 1022