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