1 /*
2  * Correctly rounded hyperbolic sine and cosine
3  *
4  * Author : Matthieu Gallet, Florent de Dinechin
5  *
6  *  This file is part of the crlibm library, developed by the Arenaire
7  * project at Ecole Normale Superieure de Lyon
8  *
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU Lesser General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23  */
24 
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include "crlibm.h"
28 #include "crlibm_private.h"
29 #include "csh_fast.h"
30 #include "triple-double.h"
31 
32 void exp13(int *exponent, double *exp_h, double *exp_m, double *exp_l, double x);
33 void expm1_13(double *exp_h, double *exp_m, double *exp_l, double x);
34 
35 /* switches on various printfs. Default 0 */
36 #define DEBUG 0
37 static const double largest_double = 0x1.fffffffffffffp1023;
38 static const double tiniest_double = 0x1.0p-1074;
39 
40 enum{RN,RD,RU,RZ};
41 
do_cosh(double x,double * preshi,double * preslo)42 static void do_cosh(double x, double* preshi, double* preslo){
43   int k;
44   db_number y;
45   double ch_hi, ch_lo, sh_hi, sh_lo;/* cosh(x) = (ch_hi + ch_lo)*(cosh(k*ln(2)) + (sh_hi + sh_lo)*(sinh(k*ln(2))) */
46   db_number  table_index_float;
47   int table_index;
48   double temp_hi, temp_lo, temp;/* some temporary variables */
49   double b_hi, b_lo,b_ca_hi, b_ca_lo, b_sa_hi, b_sa_lo;
50   double ca_hi, ca_lo, sa_hi, sa_lo; /*will be the tabulated values */
51   double tcb_hi, tsb_hi; /*results of polynomial approximations*/
52   double square_b_hi;
53   double ch_2_pk_hi, ch_2_pk_lo, ch_2_mk_hi, ch_2_mk_lo;
54   double sh_2_pk_hi, sh_2_pk_lo, sh_2_mk_hi, sh_2_mk_lo;
55   db_number two_p_plus_k, two_p_minus_k; /* 2^(k-1) + 2^(-k-1) */
56 
57   /* First range reduction*/
58   DOUBLE2INT(k, x * inv_ln_2.d)
59     if (k != 0){ /* b_hi+b_lo =  x - (ln2_hi + ln2_lo) * k */
60       temp_hi = x - ln2_hi.d * k;
61       temp_lo = -ln2_lo.d * k;
62       Add12Cond(b_hi, b_lo, temp_hi, temp_lo);
63     }
64     else {
65       b_hi = x;  b_lo = 0.;
66     }
67   /*we'll construct 2 constants for the last reconstruction */
68   two_p_plus_k.i[LO] = 0;
69   two_p_plus_k.i[HI] = (k-1+1023) << 20;
70   two_p_minus_k.i[LO] = 0;
71   two_p_minus_k.i[HI] = (-k-1+1023) << 20;
72 
73   /* at this stage, we've done the first range reduction : we have b_hi + b_lo  between -ln(2)/2 and ln(2)/2 */
74   /* now we can do the second range reduction */
75   /* we'll get the 8 leading bits of b_hi */
76   table_index_float.d = b_hi + two_43_44.d;
77   /*this add do the float equivalent of a rotation to the right, since -0.5 <= b_hi <= 0.5*/
78   table_index = table_index_float.i[LO];/* -89 <= table_index <= 89 */
79   table_index_float.d -= two_43_44.d;
80   table_index += bias; /* to have only positive values */
81   b_hi -= table_index_float.d;/* to remove the 8 leading bits*/
82   /* since b_hi was between -2^-1 and 2^1, we now have b_hi between -2^-9 and 2^-9 */
83 
84 
85   y.d = b_hi;
86   /*   first, y�  */
87   square_b_hi = b_hi * b_hi;
88   /* effective computation of the polynomial approximation */
89 
90   if (((y.i[HI])&(0x7FFFFFFF)) < (two_minus_30.i[HI])) {
91     tcb_hi = 0;
92     tsb_hi = 0;
93   }
94   else {
95     /*   second, cosh(y) = y� * (1/2 + y� * (1/24 + y� * 1/720)) */
96     tcb_hi = (square_b_hi)* (c2.d + square_b_hi * (c4.d + square_b_hi * c6.d));
97     tsb_hi = square_b_hi * (s3.d + square_b_hi * (s5.d + square_b_hi * s7.d));
98   }
99 
100 
101   if( table_index != bias) {
102     /* we get the tabulated the tabulated values */
103     ca_hi = cosh_sinh_table[table_index][0].d;
104     ca_lo = cosh_sinh_table[table_index][1].d;
105     sa_hi = cosh_sinh_table[table_index][2].d;
106     sa_lo = cosh_sinh_table[table_index][3].d;
107 
108     /* first reconstruction of the cosh (corresponding to the second range reduction) */
109     Mul12(&b_sa_hi,&b_sa_lo, sa_hi, b_hi);
110     temp =  ((((((ca_lo + (b_hi * sa_lo)) + b_lo * sa_hi) + b_sa_lo) + (b_sa_hi * tsb_hi)) + ca_hi * tcb_hi) + b_sa_hi);
111     Add12Cond(ch_hi, ch_lo, ca_hi, temp);
112       /* first reconstruction for the sinh (corresponding to the second range reduction) */
113   }
114   else {
115     Add12Cond(ch_hi, ch_lo, (double) 1, tcb_hi);
116   }
117 
118 
119   if(k != 0) {
120     if( table_index != bias) {
121       /* first reconstruction for the sinh (corresponding to the second range reduction) */
122       Mul12(&b_ca_hi , &b_ca_lo, ca_hi, b_hi);
123       temp = (((((sa_lo + (b_lo * ca_hi)) + (b_hi * ca_lo)) + b_ca_lo) + (sa_hi*tcb_hi)) + (b_ca_hi * tsb_hi));
124       Add12(temp_hi, temp_lo, b_ca_hi, temp);
125       Add22Cond(&sh_hi, &sh_lo, sa_hi, (double) 0, temp_hi, temp_lo);
126     }
127     else {
128       Add12Cond(sh_hi, sh_lo, b_hi, tsb_hi * b_hi + b_lo);
129     }
130     if((k < 35) && (k > -35) )
131       {
132 	ch_2_pk_hi = ch_hi * two_p_plus_k.d;
133 	ch_2_pk_lo = ch_lo * two_p_plus_k.d;
134 	ch_2_mk_hi = ch_hi * two_p_minus_k.d;
135 	ch_2_mk_lo = ch_lo * two_p_minus_k.d;
136 	sh_2_pk_hi = sh_hi * two_p_plus_k.d;
137 	sh_2_pk_lo = sh_lo * two_p_plus_k.d;
138 	sh_2_mk_hi = - sh_hi * two_p_minus_k.d;
139 	sh_2_mk_lo = - sh_lo * two_p_minus_k.d;
140 
141 	Add22Cond(preshi, preslo, ch_2_mk_hi, ch_2_mk_lo, sh_2_mk_hi, sh_2_mk_lo);
142 	Add22Cond(&ch_2_mk_hi, &ch_2_mk_lo , sh_2_pk_hi, sh_2_pk_lo, *preshi, *preslo);
143 	Add22Cond(preshi, preslo, ch_2_pk_hi, ch_2_pk_lo, ch_2_mk_hi, ch_2_mk_lo);
144       }
145     else if (k >= 35)
146       {
147 	ch_2_pk_hi = ch_hi * two_p_plus_k.d;
148 	ch_2_pk_lo = ch_lo * two_p_plus_k.d;
149 	sh_2_pk_hi = sh_hi * two_p_plus_k.d;
150 	sh_2_pk_lo = sh_lo * two_p_plus_k.d;
151 	Add22Cond(preshi, preslo, ch_2_pk_hi, ch_2_pk_lo, sh_2_pk_hi, sh_2_pk_lo);
152       }
153     else /* if (k <= -35) */
154       {
155 	ch_2_mk_hi = ch_hi * two_p_minus_k.d;
156 	ch_2_mk_lo = ch_lo * two_p_minus_k.d;
157 	sh_2_mk_hi = - sh_hi * two_p_minus_k.d;
158 	sh_2_mk_lo = - sh_lo * two_p_minus_k.d;
159 	Add22Cond(preshi, preslo, ch_2_mk_hi, ch_2_mk_lo, sh_2_mk_hi, sh_2_mk_lo);
160       }
161   }
162   else {
163     *preshi = ch_hi;
164     *preslo = ch_lo;
165   }
166 
167   return;
168 }
169 
170 
171 
do_cosh_accurate(int * pexponent,double * presh,double * presm,double * presl,double x)172 static void do_cosh_accurate(int* pexponent,
173 			     double* presh, double* presm, double* presl,
174 			     double x){
175   double exph, expm, expl;
176   double expph, exppm, exppl;
177   int exponentm, deltaexponent;
178   db_number  expmh, expmm, expml;
179 
180 #if EVAL_PERF==1
181   crlibm_second_step_taken++;
182 #endif
183 
184   if(x<0)
185     x=-x;
186   if (x > 40.0) {  /* then exp(-x) < 2^-118 exp(x) */
187     exp13(pexponent, presh, presm, presl, x);
188   }
189   else {
190     exp13(pexponent, &expph, &exppm, &exppl, x);
191     exp13(&exponentm, &(expmh.d), &(expmm.d), &(expml.d), -x);
192     /* align the mantissas.
193        The exponent is increased but stays well below overflow threshold */
194     deltaexponent =  exponentm - *pexponent ;
195     expmh.i[HI] += (deltaexponent) << 20;
196     expmm.i[HI] += (deltaexponent) << 20;
197     expml.i[HI] += (deltaexponent) << 20;
198     Add33(&exph, &expm, &expl, expph, exppm, exppl,   expmh.d, expmm.d, expml.d);
199     Renormalize3(presh,presm,presl, exph, expm, expl);
200   }
201 }
202 
203 
204 
cosh_rn(double x)205 double cosh_rn(double x){
206   db_number y;
207   int hx;
208   double rh, rl;
209 
210   y.d = x;
211   hx = y.i[HI] & 0x7FFFFFFF;
212 
213   /* Filter special cases */
214   if (hx > max_input_csh.i[HI]) { /* strictly greater, implies x > max_input_csh */
215     if (hx >= 0x7ff00000){  /* Infty or NaN */
216       if (((hx&0x000fffff)|y.i[LO])!=0)
217 	return x+x;                                        /* Nan */
218       else {/* otherwise the result should be +infty */
219 	y.i[HI] = 0x7FF00000;
220 	return (y.d);
221       }
222     }
223   }
224   if (x >= max_input_csh.d || x <= -max_input_csh.d)
225     return largest_double * largest_double;     /* overflow  */
226   if (hx<0x3e500000) {
227     if(x==0)
228       return 1.0; /* exact */
229     else
230       return (1.0+tiniest_double); /* to raise inexact flag */
231   }
232 
233   do_cosh(x, &rh, &rl);
234 
235 
236   if (rh == (rh + (rl * round_cst_csh))) return rh;
237   else{
238     int exponent;
239     db_number res;
240     double  resh, resm, resl;
241 
242     do_cosh_accurate(&exponent, &resh,&resm, &resl, x);
243     RoundToNearest3(&(res.d), resh, resm, resl);
244 
245     /* Now we have to set the exponent of res as exponent -1 (division
246        by 2). However, as res may sometimes end up infinite, we first
247        set the exponent to exponent -11 and then multiply by 2^10,
248        which will cater for overflow  */
249     res.i[HI] += (exponent-11) << 20;
250     return 1024. * res.d;
251   }
252 }
253 
254 
255 
256 
257 
258 
259 
260 
cosh_ru(double x)261 double cosh_ru(double x){
262   db_number y;
263   int hx;
264   double rh, rl;
265 
266   y.d = x;
267   hx = y.i[HI] & 0x7FFFFFFF;
268 
269   if (hx > max_input_csh.i[HI]) {
270     /* if NaN, return it */
271     if (((hx&0x7FF00000) == 0x7FF00000) && (((y.i[HI] & 0x000FFFFF)!=0) || (y.i[LO]!=0)) )
272       return x;
273     else {/* otherwise the result should be +infty */
274       y.i[LO] = 0; y.i[HI] = 0x7FF00000; return (y.d);
275     }
276   }
277 
278   if (x >= max_input_csh.d || x <= -max_input_csh.d)
279     return largest_double * largest_double;     /* overflow  */
280 
281   if (hx<0x3e500000) { /* return the successor of 1 */
282     if(x==0.) return 1.0;
283     else{
284       y.l = 0x3ff0000000000001LL;
285       return y.d;
286     }
287   }
288 
289   do_cosh(x, &rh, &rl);
290 
291   TEST_AND_RETURN_RU(rh, rl, maxepsilon_csh);
292 
293   /* if the previous block didn't return a value, launch accurate phase */
294   {
295     int exponent;
296     db_number res;
297     double resh, resm, resl;
298 
299     do_cosh_accurate(&exponent, &resh,&resm, &resl, x);
300     RoundUpwards3(&(res.d), resh,resm,resl);
301 
302     /* Now we have to set the exponent of res as exponent -1 (division
303        by 2). However, as res may sometimes end up infinite, we first
304        set the exponent to exponent -11 and then multiply by 2^10,
305        which will cater for overflow  */
306     res.i[HI] += (exponent-11) << 20;
307     return 1024. * res.d;
308   }
309 }
310 
311 
312 
cosh_rd(double x)313 double cosh_rd(double x){
314   db_number y;
315   int hx;
316   double rh, rl;
317 
318   y.d = x;
319   hx = y.i[HI] & 0x7FFFFFFF;
320 
321 
322   if (hx > max_input_csh.i[HI]) {
323     if (hx >= 0x7FF00000) {    /*particular cases : QNaN, SNaN, +- oo*/
324       if (((hx&0x7FF00000) == 0x7FF00000) && (((y.i[HI] & 0x000FFFFF)!=0) || (y.i[LO]!=0)) )
325 	return x; /* NaN */
326       else { /* infinity */
327 	y.i[HI] = hx;
328 	return (y.d);
329       }
330     }
331   }
332 
333   if (y.d >= max_input_csh.d || y.d  <= - max_input_csh.d) { /* out of range */
334     y.i[LO] = 0xFFFFFFFF; y.i[HI] = 0x7FEFFFFF ; return (y.d);
335   }
336 
337   if (hx<0x3e500000)
338     return (1.0);
339 
340   do_cosh(x, &rh, &rl);
341 
342   TEST_AND_RETURN_RD(rh, rl, maxepsilon_csh);
343 
344   /* if the previous block didn't return a value, launch accurate phase */
345   {
346     int exponent;
347     db_number res;
348     double resh, resm, resl;
349 
350     do_cosh_accurate(&exponent, &resh,&resm, &resl, x);
351     RoundDownwards3(&(res.d), resh,resm,resl);
352 
353     /* Now we have to set the exponent of res as exponent -1 (division
354        by 2). However, as res may sometimes end up infinite, we first
355        set the exponent to exponent -11 and then multiply by 2^10,
356        which will cater for overflow  */
357     res.i[HI] += (exponent-11) << 20;
358     return 1024. * res.d;
359   }
360 }
361 
362 
363 
cosh_rz(double x)364 double cosh_rz(double x){
365   return(cosh_rd(x));/* cosh is always positive, so rounding to -infinite is equivalent to rounding to zero */
366 }
367 
368 
369 
370 
371 
372 
373 
374 
375 
376 
do_sinh(double x,double * prh,double * prl)377 static void do_sinh(double x, double* prh, double* prl){
378 
379   int k;
380   db_number y;
381   double temp1;
382   double ch_hi, ch_lo, sh_hi, sh_lo;/* cosh(x) = (sh_hi + sh_lo)*(cosh(k*ln(2)) + (ch_hi + ch_lo)*(sinh(k*ln(2))) */
383   db_number  table_index_float;
384   int table_index;
385   double ch_2_pk_hi, ch_2_pk_lo, ch_2_mk_hi, ch_2_mk_lo;
386   double sh_2_pk_hi, sh_2_pk_lo, sh_2_mk_hi, sh_2_mk_lo;
387   double b_hi, b_lo;
388   double ca_b_hi, ca_b_lo, temp_hi, temp_lo, sa_b_hi, sa_b_lo;
389   double ca_hi, ca_lo, sa_hi, sa_lo; /*tabulated values */
390   double tcb_hi,  tsb_hi; /*results of polynomial approximations*/
391   db_number two_p_plus_k, two_p_minus_k; /* 2^(k-1) + 2^(-k-1) */
392   double square_y_hi;
393 
394   /* Now we can do the first range reduction*/
395   DOUBLE2INT(k, x * inv_ln_2.d)
396     if (k != 0){ /* b_hi + b_lo =  x - (ln2_hi + ln2_lo) * k */
397       temp_hi = x - ln2_hi.d * k;
398       temp_lo = -ln2_lo.d * k;
399       Add12Cond(b_hi, b_lo, temp_hi, temp_lo);
400     }
401     else {
402       b_hi = x;  b_lo = 0.;
403     }
404 
405   /*we'll construct 2 constants for the last reconstruction */
406   two_p_plus_k.i[LO] = 0;
407   two_p_plus_k.i[HI] = (k-1+1023) << 20;
408   two_p_minus_k.i[LO] = 0;
409   two_p_minus_k.i[HI] = (-k-1+1023) << 20;
410 
411   /* at this stage, we've done the first range reduction : we have b_hi + b_lo  between -ln(2)/2 and ln(2)/2 */
412   /* now we can do the second range reduction */
413   /* we'll get the 8 leading bits of r_hi */
414 
415   table_index_float.d = b_hi + two_43_44.d;
416   /*this add do the float equivalent of a rotation to the right, since -0.5 <= b_hi <= 0.5*/
417   table_index = table_index_float.i[LO];/* -89 <= table_index <= 89 */
418   table_index_float.d -= two_43_44.d;
419   table_index += bias; /* to have only positive values */
420   b_hi -= table_index_float.d;/* to remove the 8 leading bits*/
421   /* since b_hi was between -2^-1 and 2^1, we now have b_hi between -2^-9 and 2^-9 */
422 
423   y.d = b_hi;
424   /*   first, y� = square_y_hi + square_y_lo  */
425   square_y_hi = b_hi * b_hi;
426   /* effective computation of the polyomial approximation */
427   if (((y.i[HI])&(0x7FFFFFFF)) <= (two_minus_30.i[HI])) {
428     tsb_hi = 0;
429     tcb_hi = 0;
430   }
431   else {
432     tsb_hi = square_y_hi * (s3.d + square_y_hi * (s5.d + square_y_hi * s7.d));
433     /*   second, cosh(y) = y� * (1/2 + y� * (1/24 + y� * 1/720)) */
434     tcb_hi = (square_y_hi)* (c2.d + square_y_hi * (c4.d + square_y_hi * c6.d));
435   }
436 
437   if( table_index != bias) {
438     /* we get the tabulated the tabulated values*/
439     ca_hi = cosh_sinh_table[table_index][0].d;
440     ca_lo = cosh_sinh_table[table_index][1].d;
441     sa_hi = cosh_sinh_table[table_index][2].d;
442     sa_lo = cosh_sinh_table[table_index][3].d;
443 
444     /* first reconstruction for the sinh (corresponding to the second range reduction) */
445     temp1 = sa_lo;
446     temp1 += b_lo * ca_hi;
447     temp1 += b_hi * ca_lo;
448     Mul12(&ca_b_hi, &ca_b_lo, ca_hi, b_hi);
449     temp1 += ca_b_lo;
450     temp1 += sa_hi * tcb_hi;
451     temp1 += ca_b_hi * tsb_hi;
452     Add12Cond(temp_hi, temp_lo, ca_b_hi, temp1);
453     Add22Cond(&sh_hi, &sh_lo, sa_hi, (double) 0, temp_hi, temp_lo);
454     /* first reconstruction of the cosh (corresponding to the second range reduction) */
455     temp1 = ca_lo;
456     Mul12(&sa_b_hi,&sa_b_lo, sa_hi, b_hi);
457     temp1 += b_hi * sa_lo;
458     temp1 += b_lo * sa_hi;
459     temp1 += sa_b_lo;
460     temp1 += sa_b_hi * tsb_hi;
461     temp1 += ca_hi * tcb_hi;
462     temp1 += sa_b_hi;
463     Add12Cond(ch_hi, ch_lo, ca_hi, temp1);
464   }
465   else {
466     Add12Cond(sh_hi, sh_lo, b_hi, tsb_hi * b_hi + b_lo);
467     Add12Cond(ch_hi, ch_lo, (double) 1, tcb_hi);
468   }
469 
470   if(k != 0) {
471     if( (k < 35) && (k > -35) ) {
472 	ch_2_pk_hi = ch_hi * two_p_plus_k.d;
473 	ch_2_pk_lo = ch_lo * two_p_plus_k.d;
474 	ch_2_mk_hi = - ch_hi * two_p_minus_k.d;
475 	ch_2_mk_lo = - ch_lo * two_p_minus_k.d;
476 	sh_2_pk_hi = sh_hi * two_p_plus_k.d;
477 	sh_2_pk_lo = sh_lo * two_p_plus_k.d;
478 	sh_2_mk_hi = sh_hi * two_p_minus_k.d;
479 	sh_2_mk_lo = sh_lo * two_p_minus_k.d;
480 
481 	Add22Cond(prh, prl, ch_2_mk_hi, ch_2_mk_lo, sh_2_mk_hi, sh_2_mk_lo);
482 	Add22Cond(&ch_2_mk_hi, &ch_2_mk_lo , sh_2_pk_hi, sh_2_pk_lo, *prh, *prl);
483 	Add22Cond(prh, prl, ch_2_pk_hi, ch_2_pk_lo, ch_2_mk_hi, ch_2_mk_lo);
484     }
485     else if (k >= 35)
486       {
487 	ch_2_pk_hi = ch_hi * two_p_plus_k.d;
488 	ch_2_pk_lo = ch_lo * two_p_plus_k.d;
489 	sh_2_pk_hi = sh_hi * two_p_plus_k.d;
490 	sh_2_pk_lo = sh_lo * two_p_plus_k.d;
491 	Add22Cond(prh, prl, ch_2_pk_hi, ch_2_pk_lo, sh_2_pk_hi, sh_2_pk_lo);
492       }
493     else
494       {
495 	ch_2_mk_hi = - ch_hi * two_p_minus_k.d;
496 	ch_2_mk_lo = - ch_lo * two_p_minus_k.d;
497 	sh_2_mk_hi = sh_hi * two_p_minus_k.d;
498 	sh_2_mk_lo = sh_lo * two_p_minus_k.d;
499 	Add22Cond(prh, prl, ch_2_mk_hi, ch_2_mk_lo, sh_2_mk_hi, sh_2_mk_lo);
500       }
501   }
502   else {
503     *prh = sh_hi;
504     *prl = sh_lo;
505   }
506 }
507 
508 
509 
510 
511 
do_sinh_accurate(int * pexponent,double * presh,double * presm,double * presl,double x)512 static void do_sinh_accurate(int* pexponent,
513 			     double* presh, double* presm, double* presl,
514 			     double x){
515   double exph, expm, expl;
516   double expph, exppm, exppl, expmh, expmm, expml;
517 
518 #if EVAL_PERF==1
519   crlibm_second_step_taken++;
520 #endif
521 
522   if(x > 40.0) { /* then exp(-x) < 2^-129 exp(x) */
523     exp13(pexponent, presh, presm, presl, x);
524     return;
525   }
526   if(x < -40.0) { /* then exp(x) < 2^-129 exp(-x) */
527     exp13(pexponent, presh, presm, presl, -x);
528     *presh = -*presh;
529     *presm = -*presm;
530     *presl = -*presl;
531     return;
532   }
533   /* Otherwise we are between -40 and 40, and we also know that |x| > 2^-25 */
534   if(x>0.0) {
535     expm1_13(&expph, &exppm, &exppl, x);
536     expm1_13(&expmh, &expmm, &expml, -x);
537     /* The following is OK because expph and  -expmh have the same sign */
538     Add33(&exph, &expm, &expl, expph, exppm, exppl,   -expmh, -expmm, -expml);
539     Renormalize3(presh,presm,presl, exph, expm, expl);
540     *pexponent=0;
541     return;
542   }
543   else  { /* x<0 */
544     expm1_13(&expph, &exppm, &exppl, x);
545     expm1_13(&expmh, &expmm, &expml, -x);
546     /* The following is OK because expph and  -expmh have the same sign */
547     Add33(&exph, &expm, &expl,   -expmh, -expmm, -expml, expph, exppm, exppl);
548     Renormalize3(presh,presm,presl, exph, expm, expl);
549     *pexponent=0;
550     return;
551   }
552 }
553 
554 
555 
556 
sinh_rn(double x)557 double sinh_rn(double x){
558   db_number y;
559   int hx;
560   double rh, rl;
561 
562 
563   y.d = x;
564   hx = y.i[HI] & 0x7FFFFFFF;
565 
566   /* Filter special cases */
567   if (hx > max_input_csh.i[HI]) { /* strictly greater, implies x > max_input_csh */
568     if (hx >= 0x7ff00000){ /* infinity or NaN */
569       if (((hx&0x000fffff)|y.i[LO])!=0)
570 	return x+x;                                        /* NaN */
571       else {/* otherwise the result should be +infty */
572 	return (y.d);
573       }
574     }
575     if (x > max_input_csh.d)
576       return largest_double * largest_double;     /* overflow  */
577     if (x < -max_input_csh.d)
578       return -largest_double * largest_double;     /* overflow  */
579   }
580 
581   if (hx<0x3e500000) {
582       return x; /* exact, we should find some way of raising the inexact flag */
583   }
584 
585 
586   do_sinh(x, &rh, &rl);
587 
588   if (rh == (rh + (rl * round_cst_csh))) return rh;
589   else{
590     int exponent;
591     db_number res;
592     double  resh, resm, resl;
593 
594     do_sinh_accurate(&exponent, &resh,&resm, &resl, x);
595     RoundToNearest3(&(res.d), resh, resm, resl);
596 
597     /* Now we have to set the exponent of res as exponent -1 (division
598        by 2). However, as res may sometimes end up infinite, we first
599        set the exponent to exponent -11 and then multiply by 2^10,
600        which will cater for overflow  */
601     res.i[HI] += (exponent-11) << 20;
602     return 1024. * res.d;
603   }
604 
605 }
606 
607 
608 
sinh_ru(double x)609 double sinh_ru(double x){
610   db_number y;
611   double rh, rl;
612 
613 
614   y.d = x;
615   y.i[HI] = y.i[HI] & 0x7FFFFFFF;     /* to get the absolute value of the input */
616   if ((y.i[HI] & 0x7FF00000) >= (0x7FF00000)) {    /*particular cases : QNaN, SNaN, +- oo*/
617    return (x);
618   }
619   if (y.d > max_input_csh.d) { /* out of range */
620     if(x>0) {
621       y.i[LO] = 0; y.i[HI] = 0x7FF00000; return (y.d);
622     }
623     else {
624       y.i[LO] = 0xFFFFFFFF; y.i[HI] = 0xFFEFFFFF ; return (y.d);
625     }
626   }
627 
628   if(y.i[HI] < 0x3e500000) /* 2^(-26) */
629     { /* Add one ulp if x positive */
630       if(x>0) {
631 	y.l++;
632 	return y.d;
633       }
634       else
635 	return x;
636     }
637 
638   do_sinh(x, &rh, &rl);
639 
640   TEST_AND_RETURN_RU(rh, rl, maxepsilon_csh);
641 
642   /* if the previous block didn't return a value, launch accurate phase */
643   {
644     int exponent;
645     db_number res;
646     double resh, resm, resl;
647 
648     do_sinh_accurate(&exponent, &resh,&resm, &resl, x);
649     RoundUpwards3(&(res.d), resh,resm,resl);
650 
651     /* Now we have to set the exponent of res as exponent -1 (division
652        by 2). However, as res may sometimes end up infinite, we first
653        set the exponent to exponent -11 and then multiply by 2^10,
654        which will cater for overflow  */
655     res.i[HI] += (exponent-11) << 20;
656     return 1024. * res.d;
657   }
658 }
659 
660 
sinh_rd(double x)661 double sinh_rd(double x){
662   db_number y;
663   double rh, rl;
664 
665   y.d = x;
666   y.i[HI] = y.i[HI] & 0x7FFFFFFF;     /* to get the absolute value of the input */
667   if ((y.i[HI] & 0x7FF00000) >= (0x7FF00000)) {    /*particular cases : QNaN, SNaN, +- oo*/
668     y.d = x;
669    return (y.d);
670   }
671   if (y.d > max_input_csh.d) { /* out of range */
672     if(x>0) {
673       y.i[LO] = 0xFFFFFFFF; y.i[HI] = 0x7FEFFFFF ; return (y.d);
674     }
675     else {
676       y.i[LO] = 0; y.i[HI] = 0xFFF00000; return (y.d);
677     }
678   }
679   if(y.i[HI] < 0x3e500000) /* 2^(-26) */
680     { /* Add one ulp and restore the sign if x negative */
681       if(x<0){
682 	y.l = (y.l+1);
683 	return -y.d;
684       }
685       else
686 	return x;
687     }
688   do_sinh(x, &rh, &rl);
689 
690   TEST_AND_RETURN_RD(rh, rl, maxepsilon_csh);
691 
692   /* if the previous block didn't return a value, launch accurate phase */
693   {
694     int exponent;
695     db_number res;
696     double resh, resm, resl;
697 
698     do_sinh_accurate(&exponent, &resh,&resm, &resl, x);
699     RoundDownwards3(&(res.d), resh,resm,resl);
700 
701     /* Now we have to set the exponent of res as exponent -1 (division
702        by 2). However, as res may sometimes end up infinite, we first
703        set the exponent to exponent -11 and then multiply by 2^10,
704        which will cater for overflow  */
705     res.i[HI] += (exponent-11) << 20;
706     return 1024. * res.d;
707   }
708 }
709 
710 
711 
712 
sinh_rz(double x)713 double sinh_rz(double x){
714   if( x > 0) {
715     return(sinh_rd(x));
716   }
717   else {
718     return(sinh_ru(x));
719   }
720 }
721 
722