intervals 0.3.56

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. data/VERSION.txt +1 -0
  2. data/ext/crlibm/AUTHORS +2 -0
  3. data/ext/crlibm/COPYING +504 -0
  4. data/ext/crlibm/ChangeLog +80 -0
  5. data/ext/crlibm/INSTALL +182 -0
  6. data/ext/crlibm/Makefile.am +84 -0
  7. data/ext/crlibm/Makefile.in +530 -0
  8. data/ext/crlibm/NEWS +0 -0
  9. data/ext/crlibm/README +31 -0
  10. data/ext/crlibm/TODO +47 -0
  11. data/ext/crlibm/VERSION +1 -0
  12. data/ext/crlibm/aclocal.m4 +989 -0
  13. data/ext/crlibm/atan-itanium.c +846 -0
  14. data/ext/crlibm/atan-pentium.c +261 -0
  15. data/ext/crlibm/atan_accurate.c +244 -0
  16. data/ext/crlibm/atan_accurate.h +191 -0
  17. data/ext/crlibm/atan_fast.c +324 -0
  18. data/ext/crlibm/atan_fast.h +678 -0
  19. data/ext/crlibm/config.guess +1461 -0
  20. data/ext/crlibm/config.sub +1566 -0
  21. data/ext/crlibm/configure +7517 -0
  22. data/ext/crlibm/configure.ac +364 -0
  23. data/ext/crlibm/crlibm.h +125 -0
  24. data/ext/crlibm/crlibm_config.h +149 -0
  25. data/ext/crlibm/crlibm_config.h.in +148 -0
  26. data/ext/crlibm/crlibm_private.c +293 -0
  27. data/ext/crlibm/crlibm_private.h +658 -0
  28. data/ext/crlibm/csh_fast.c +631 -0
  29. data/ext/crlibm/csh_fast.h +771 -0
  30. data/ext/crlibm/double-extended.h +496 -0
  31. data/ext/crlibm/exp-td.c +962 -0
  32. data/ext/crlibm/exp-td.h +685 -0
  33. data/ext/crlibm/exp_accurate.c +197 -0
  34. data/ext/crlibm/exp_accurate.h +85 -0
  35. data/ext/crlibm/gappa/log-de-E0-logir0.gappa +106 -0
  36. data/ext/crlibm/gappa/log-de-E0.gappa +79 -0
  37. data/ext/crlibm/gappa/log-de.gappa +81 -0
  38. data/ext/crlibm/gappa/log-td-E0-logir0.gappa +126 -0
  39. data/ext/crlibm/gappa/log-td-E0.gappa +143 -0
  40. data/ext/crlibm/gappa/log-td-accurate-E0-logir0.gappa +230 -0
  41. data/ext/crlibm/gappa/log-td-accurate-E0.gappa +213 -0
  42. data/ext/crlibm/gappa/log-td-accurate.gappa +217 -0
  43. data/ext/crlibm/gappa/log-td.gappa +156 -0
  44. data/ext/crlibm/gappa/trigoSinCosCase3.gappa +204 -0
  45. data/ext/crlibm/gappa/trigoTanCase2.gappa +73 -0
  46. data/ext/crlibm/install-sh +269 -0
  47. data/ext/crlibm/log-de.c +431 -0
  48. data/ext/crlibm/log-de.h +732 -0
  49. data/ext/crlibm/log-td.c +852 -0
  50. data/ext/crlibm/log-td.h +819 -0
  51. data/ext/crlibm/log10-td.c +906 -0
  52. data/ext/crlibm/log10-td.h +823 -0
  53. data/ext/crlibm/log2-td.c +935 -0
  54. data/ext/crlibm/log2-td.h +821 -0
  55. data/ext/crlibm/maple/atan.mpl +359 -0
  56. data/ext/crlibm/maple/common-procedures.mpl +997 -0
  57. data/ext/crlibm/maple/csh.mpl +446 -0
  58. data/ext/crlibm/maple/double-extended.mpl +151 -0
  59. data/ext/crlibm/maple/exp-td.mpl +195 -0
  60. data/ext/crlibm/maple/log-de.mpl +243 -0
  61. data/ext/crlibm/maple/log-td.mpl +316 -0
  62. data/ext/crlibm/maple/log10-td.mpl +345 -0
  63. data/ext/crlibm/maple/log2-td.mpl +334 -0
  64. data/ext/crlibm/maple/trigo.mpl +728 -0
  65. data/ext/crlibm/maple/triple-double.mpl +58 -0
  66. data/ext/crlibm/missing +198 -0
  67. data/ext/crlibm/mkinstalldirs +40 -0
  68. data/ext/crlibm/rem_pio2_accurate.c +219 -0
  69. data/ext/crlibm/rem_pio2_accurate.h +53 -0
  70. data/ext/crlibm/scs_lib/AUTHORS +3 -0
  71. data/ext/crlibm/scs_lib/COPYING +504 -0
  72. data/ext/crlibm/scs_lib/ChangeLog +16 -0
  73. data/ext/crlibm/scs_lib/INSTALL +215 -0
  74. data/ext/crlibm/scs_lib/Makefile.am +18 -0
  75. data/ext/crlibm/scs_lib/Makefile.in +328 -0
  76. data/ext/crlibm/scs_lib/NEWS +0 -0
  77. data/ext/crlibm/scs_lib/README +9 -0
  78. data/ext/crlibm/scs_lib/TODO +4 -0
  79. data/ext/crlibm/scs_lib/addition_scs.c +623 -0
  80. data/ext/crlibm/scs_lib/config.guess +1461 -0
  81. data/ext/crlibm/scs_lib/config.sub +1566 -0
  82. data/ext/crlibm/scs_lib/configure +6226 -0
  83. data/ext/crlibm/scs_lib/division_scs.c +110 -0
  84. data/ext/crlibm/scs_lib/double2scs.c +174 -0
  85. data/ext/crlibm/scs_lib/install-sh +269 -0
  86. data/ext/crlibm/scs_lib/missing +198 -0
  87. data/ext/crlibm/scs_lib/mkinstalldirs +40 -0
  88. data/ext/crlibm/scs_lib/multiplication_scs.c +456 -0
  89. data/ext/crlibm/scs_lib/poly_fct.c +112 -0
  90. data/ext/crlibm/scs_lib/print_scs.c +73 -0
  91. data/ext/crlibm/scs_lib/rand_scs.c +63 -0
  92. data/ext/crlibm/scs_lib/scs.h +353 -0
  93. data/ext/crlibm/scs_lib/scs2double.c +391 -0
  94. data/ext/crlibm/scs_lib/scs2mpf.c +58 -0
  95. data/ext/crlibm/scs_lib/scs2mpfr.c +61 -0
  96. data/ext/crlibm/scs_lib/scs_private.c +23 -0
  97. data/ext/crlibm/scs_lib/scs_private.h +133 -0
  98. data/ext/crlibm/scs_lib/tests/tbx_timing.h +102 -0
  99. data/ext/crlibm/scs_lib/wrapper_scs.h +486 -0
  100. data/ext/crlibm/scs_lib/zero_scs.c +52 -0
  101. data/ext/crlibm/stamp-h.in +1 -0
  102. data/ext/crlibm/tests/Makefile.am +43 -0
  103. data/ext/crlibm/tests/Makefile.in +396 -0
  104. data/ext/crlibm/tests/blind_test.c +148 -0
  105. data/ext/crlibm/tests/generate_test_vectors.c +258 -0
  106. data/ext/crlibm/tests/soak_test.c +334 -0
  107. data/ext/crlibm/tests/test_common.c +627 -0
  108. data/ext/crlibm/tests/test_common.h +28 -0
  109. data/ext/crlibm/tests/test_perf.c +570 -0
  110. data/ext/crlibm/tests/test_val.c +249 -0
  111. data/ext/crlibm/trigo_accurate.c +500 -0
  112. data/ext/crlibm/trigo_accurate.h +331 -0
  113. data/ext/crlibm/trigo_fast.c +1219 -0
  114. data/ext/crlibm/trigo_fast.h +639 -0
  115. data/ext/crlibm/triple-double.h +878 -0
  116. data/ext/extconf.rb +31 -0
  117. data/ext/fpu.c +107 -0
  118. data/ext/jamis-mod.rb +591 -0
  119. data/lib/fpu.rb +287 -0
  120. data/lib/interval.rb +1170 -0
  121. data/lib/intervals.rb +212 -0
  122. data/lib/struct_float.rb +133 -0
  123. data/test/data_atan.txt +360 -0
  124. data/test/data_cos.txt +346 -0
  125. data/test/data_cosh.txt +3322 -0
  126. data/test/data_exp.txt +3322 -0
  127. data/test/data_log.txt +141 -0
  128. data/test/data_sin.txt +140 -0
  129. data/test/data_sinh.txt +3322 -0
  130. data/test/data_tan.txt +342 -0
  131. metadata +186 -0
@@ -0,0 +1,631 @@
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 "exp_accurate.h"
31
+
32
+
33
+ /* switches on various printfs. Default 0 */
34
+ #define DEBUG 0
35
+ static const double largest_double = 0x1.fffffffffffffp1023;
36
+ static const double tiniest_double = 0x1.0p-1074;
37
+
38
+ enum{RN,RD,RU,RZ};
39
+
40
+ static void do_cosh(double x, double* preshi, double* preslo){
41
+ int k;
42
+ db_number y;
43
+ 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))) */
44
+ db_number table_index_float;
45
+ int table_index;
46
+ double temp_hi, temp_lo, temp;/* some temporary variables */
47
+ double b_hi, b_lo,b_ca_hi, b_ca_lo, b_sa_hi, b_sa_lo;
48
+ double ca_hi, ca_lo, sa_hi, sa_lo; /*will be the tabulated values */
49
+ double tcb_hi, tsb_hi; /*results of polynomial approximations*/
50
+ double square_b_hi;
51
+ double ch_2_pk_hi, ch_2_pk_lo, ch_2_mk_hi, ch_2_mk_lo;
52
+ double sh_2_pk_hi, sh_2_pk_lo, sh_2_mk_hi, sh_2_mk_lo;
53
+ db_number two_p_plus_k, two_p_minus_k; /* 2^(k-1) + 2^(-k-1) */
54
+
55
+ /* First range reduction*/
56
+ DOUBLE2INT(k, x * inv_ln_2.d)
57
+ if (k != 0){ /* b_hi+b_lo = x - (ln2_hi + ln2_lo) * k */
58
+ temp_hi = x - ln2_hi.d * k;
59
+ temp_lo = -ln2_lo.d * k;
60
+ Add12Cond(b_hi, b_lo, temp_hi, temp_lo);
61
+ }
62
+ else {
63
+ b_hi = x; b_lo = 0.;
64
+ }
65
+ /*we'll construct 2 constants for the last reconstruction */
66
+ two_p_plus_k.i[LO] = 0;
67
+ two_p_plus_k.i[HI] = (k-1+1023) << 20;
68
+ two_p_minus_k.i[LO] = 0;
69
+ two_p_minus_k.i[HI] = (-k-1+1023) << 20;
70
+
71
+ /* at this stage, we've done the first range reduction : we have b_hi + b_lo between -ln(2)/2 and ln(2)/2 */
72
+ /* now we can do the second range reduction */
73
+ /* we'll get the 8 leading bits of b_hi */
74
+ table_index_float.d = b_hi + two_43_44.d;
75
+ /*this add do the float equivalent of a rotation to the right, since -0.5 <= b_hi <= 0.5*/
76
+ table_index = table_index_float.i[LO];/* -89 <= table_index <= 89 */
77
+ table_index_float.d -= two_43_44.d;
78
+ table_index += bias; /* to have only positive values */
79
+ b_hi -= table_index_float.d;/* to remove the 8 leading bits*/
80
+ /* since b_hi was between -2^-1 and 2^1, we now have b_hi between -2^-9 and 2^-9 */
81
+
82
+
83
+ y.d = b_hi;
84
+ /* first, y� */
85
+ square_b_hi = b_hi * b_hi;
86
+ /* effective computation of the polynomial approximation */
87
+
88
+ if (((y.i[HI])&(0x7FFFFFFF)) < (two_minus_30.i[HI])) {
89
+ tcb_hi = 0;
90
+ tsb_hi = 0;
91
+ }
92
+ else {
93
+ /* second, cosh(y) = y� * (1/2 + y� * (1/24 + y� * 1/720)) */
94
+ tcb_hi = (square_b_hi)* (c2.d + square_b_hi * (c4.d + square_b_hi * c6.d));
95
+ tsb_hi = square_b_hi * (s3.d + square_b_hi * (s5.d + square_b_hi * s7.d));
96
+ }
97
+
98
+
99
+ if( table_index != bias) {
100
+ /* we get the tabulated the tabulated values */
101
+ ca_hi = cosh_sinh_table[table_index][0].d;
102
+ ca_lo = cosh_sinh_table[table_index][1].d;
103
+ sa_hi = cosh_sinh_table[table_index][2].d;
104
+ sa_lo = cosh_sinh_table[table_index][3].d;
105
+
106
+ /* first reconstruction of the cosh (corresponding to the second range reduction) */
107
+ Mul12(&b_sa_hi,&b_sa_lo, sa_hi, b_hi);
108
+ 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);
109
+ Add12Cond(ch_hi, ch_lo, ca_hi, temp);
110
+ /* first reconstruction for the sinh (corresponding to the second range reduction) */
111
+ }
112
+ else {
113
+ Add12Cond(ch_hi, ch_lo, (double) 1, tcb_hi);
114
+ }
115
+
116
+
117
+ if(k != 0) {
118
+ if( table_index != bias) {
119
+ /* first reconstruction for the sinh (corresponding to the second range reduction) */
120
+ Mul12(&b_ca_hi , &b_ca_lo, ca_hi, b_hi);
121
+ temp = (((((sa_lo + (b_lo * ca_hi)) + (b_hi * ca_lo)) + b_ca_lo) + (sa_hi*tcb_hi)) + (b_ca_hi * tsb_hi));
122
+ Add12(temp_hi, temp_lo, b_ca_hi, temp);
123
+ Add22Cond(&sh_hi, &sh_lo, sa_hi, (double) 0, temp_hi, temp_lo);
124
+ }
125
+ else {
126
+ Add12Cond(sh_hi, sh_lo, b_hi, tsb_hi * b_hi + b_lo);
127
+ }
128
+ if((k < 35) && (k > -35) )
129
+ {
130
+ ch_2_pk_hi = ch_hi * two_p_plus_k.d;
131
+ ch_2_pk_lo = ch_lo * two_p_plus_k.d;
132
+ ch_2_mk_hi = ch_hi * two_p_minus_k.d;
133
+ ch_2_mk_lo = ch_lo * two_p_minus_k.d;
134
+ sh_2_pk_hi = sh_hi * two_p_plus_k.d;
135
+ sh_2_pk_lo = sh_lo * two_p_plus_k.d;
136
+ sh_2_mk_hi = - sh_hi * two_p_minus_k.d;
137
+ sh_2_mk_lo = - sh_lo * two_p_minus_k.d;
138
+
139
+ Add22Cond(preshi, preslo, ch_2_mk_hi, ch_2_mk_lo, sh_2_mk_hi, sh_2_mk_lo);
140
+ Add22Cond(&ch_2_mk_hi, &ch_2_mk_lo , sh_2_pk_hi, sh_2_pk_lo, *preshi, *preslo);
141
+ Add22Cond(preshi, preslo, ch_2_pk_hi, ch_2_pk_lo, ch_2_mk_hi, ch_2_mk_lo);
142
+ }
143
+ else if (k >= 35)
144
+ {
145
+ ch_2_pk_hi = ch_hi * two_p_plus_k.d;
146
+ ch_2_pk_lo = ch_lo * two_p_plus_k.d;
147
+ sh_2_pk_hi = sh_hi * two_p_plus_k.d;
148
+ sh_2_pk_lo = sh_lo * two_p_plus_k.d;
149
+ Add22Cond(preshi, preslo, ch_2_pk_hi, ch_2_pk_lo, sh_2_pk_hi, sh_2_pk_lo);
150
+ }
151
+ else /* if (k <= -35) */
152
+ {
153
+ ch_2_mk_hi = ch_hi * two_p_minus_k.d;
154
+ ch_2_mk_lo = ch_lo * two_p_minus_k.d;
155
+ sh_2_mk_hi = - sh_hi * two_p_minus_k.d;
156
+ sh_2_mk_lo = - sh_lo * two_p_minus_k.d;
157
+ Add22Cond(preshi, preslo, ch_2_mk_hi, ch_2_mk_lo, sh_2_mk_hi, sh_2_mk_lo);
158
+ }
159
+ }
160
+ else {
161
+ *preshi = ch_hi;
162
+ *preslo = ch_lo;
163
+ }
164
+
165
+ return;
166
+ }
167
+
168
+
169
+
170
+ static void do_cosh_accurate(double x, scs_ptr res_scs){
171
+ int k;
172
+ scs_t exp_scs, exp_minus_scs;
173
+
174
+ #if EVAL_PERF==1
175
+ crlibm_second_step_taken++;
176
+ #endif
177
+
178
+ DOUBLE2INT(k, x * inv_ln_2.d);
179
+ if ((k > -65) && (k < 65)) {
180
+ exp_SC(exp_scs, x);
181
+ scs_inv(exp_minus_scs, exp_scs);
182
+ scs_add(res_scs, exp_scs, exp_minus_scs);
183
+ scs_div_2(res_scs);
184
+ }
185
+ else if (k >= 65) {
186
+ exp_SC(res_scs, x);
187
+ scs_div_2(res_scs);
188
+ }
189
+ else {
190
+ exp_SC(res_scs, -x);
191
+ scs_div_2(res_scs);
192
+ }
193
+ }
194
+
195
+
196
+
197
+ double cosh_rn(double x){
198
+ db_number y;
199
+ int hx;
200
+ double rh, rl;
201
+ scs_t res_scs;
202
+
203
+ y.d = x;
204
+ hx = y.i[HI] & 0x7FFFFFFF;
205
+
206
+ /* Filter special cases */
207
+ if (hx > max_input_csh.i[HI]) { /* strictly greater, implies x > max_input_csh */
208
+ if (hx >= 0x7ff00000){ /* Infty or NaN */
209
+ if (((hx&0x000fffff)|y.i[LO])!=0)
210
+ return x+x; /* Nan */
211
+ else {/* otherwise the result should be +infty */
212
+ y.i[HI] = 0x7FF00000;
213
+ return (y.d);
214
+ }
215
+ }
216
+ if (x > max_input_csh.d || x < -max_input_csh.d)
217
+ return largest_double * largest_double; /* overflow */
218
+ }
219
+ if (hx<0x3e500000) {
220
+ if(x==0)
221
+ return 1.0; /* exact */
222
+ else
223
+ return (1.0+tiniest_double); /* to raise inexact flag */
224
+ }
225
+
226
+ do_cosh(x, &rh, &rl);
227
+
228
+
229
+ if (rh == (rh + (rl * round_cst_csh))) return rh;
230
+ else{
231
+ do_cosh_accurate(x, res_scs);
232
+ scs_get_d(&rh, res_scs);
233
+ return rh;
234
+ }
235
+ }
236
+
237
+
238
+
239
+
240
+
241
+
242
+
243
+ double cosh_ru(double x){
244
+ db_number y;
245
+ int hx;
246
+ double rh, rl;
247
+ scs_t res_scs;
248
+
249
+ y.d = x;
250
+ hx = y.i[HI] & 0x7FFFFFFF;
251
+
252
+ if (hx > max_input_csh.i[HI]) {
253
+ /* if NaN, return it */
254
+ if (((hx&0x7FF00000) == 0x7FF00000) && (((y.i[HI] & 0x000FFFFF)!=0) || (y.i[LO]!=0)) )
255
+ return x;
256
+ else {/* otherwise the result should be +infty */
257
+ y.i[LO] = 0; y.i[HI] = 0x7FF00000; return (y.d);
258
+ }
259
+ }
260
+
261
+ if (hx<0x3e500000) { /* return the successor of 1 */
262
+ if(x==0.) return 1.0;
263
+ else{
264
+ y.l = 0x3ff0000000000001LL;
265
+ return y.d;
266
+ }
267
+ }
268
+
269
+ do_cosh(x, &rh, &rl);
270
+
271
+ TEST_AND_RETURN_RU(rh, rl, maxepsilon_csh);
272
+
273
+ /* if the previous block didn't return a value, launch accurate phase */
274
+ do_cosh_accurate(x, res_scs);
275
+ scs_get_d_pinf(&rh, res_scs);
276
+ return rh;
277
+ }
278
+
279
+
280
+
281
+ double cosh_rd(double x){
282
+ db_number y;
283
+ int hx;
284
+ double rh, rl;
285
+ scs_t res_scs;
286
+
287
+ y.d = x;
288
+ hx = y.i[HI] & 0x7FFFFFFF;
289
+
290
+
291
+ if (hx > max_input_csh.i[HI]) {
292
+ if (hx >= 0x7FF00000) { /*particular cases : QNaN, SNaN, +- oo*/
293
+ if (((hx&0x7FF00000) == 0x7FF00000) && (((y.i[HI] & 0x000FFFFF)!=0) || (y.i[LO]!=0)) )
294
+ return x; /* NaN */
295
+ else { /* infinity */
296
+ y.i[HI] = hx;
297
+ return (y.d);
298
+ }
299
+
300
+ }
301
+ if (y.d > max_input_csh.d || y.d < max_input_csh.d) { /* out of range */
302
+ y.i[LO] = 0xFFFFFFFF; y.i[HI] = 0x7FEFFFFF ; return (y.d);
303
+ }
304
+ }
305
+
306
+ if (hx<0x3e500000)
307
+ return (1.0);
308
+
309
+ do_cosh(x, &rh, &rl);
310
+
311
+ TEST_AND_RETURN_RD(rh, rl, maxepsilon_csh);
312
+
313
+ /* if the previous block didn't return a value, launch accurate phase */
314
+ do_cosh_accurate(x, res_scs);
315
+ scs_get_d_minf(&rh, res_scs);
316
+ return rh;
317
+ }
318
+
319
+
320
+
321
+ double cosh_rz(double x){
322
+ return(cosh_rd(x));/* cosh is always positive, so rounding to -infinite is equivalent to rounding to zero */
323
+ }
324
+
325
+
326
+
327
+
328
+
329
+
330
+
331
+
332
+
333
+
334
+ static void do_sinh(double x, double* prh, double* prl){
335
+
336
+ int k;
337
+ db_number y;
338
+ double temp1;
339
+ 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))) */
340
+ db_number table_index_float;
341
+ int table_index;
342
+ double ch_2_pk_hi, ch_2_pk_lo, ch_2_mk_hi, ch_2_mk_lo;
343
+ double sh_2_pk_hi, sh_2_pk_lo, sh_2_mk_hi, sh_2_mk_lo;
344
+ double b_hi, b_lo;
345
+ double ca_b_hi, ca_b_lo, temp_hi, temp_lo, sa_b_hi, sa_b_lo;
346
+ double ca_hi, ca_lo, sa_hi, sa_lo; /*tabulated values */
347
+ double tcb_hi, tsb_hi; /*results of polynomial approximations*/
348
+ db_number two_p_plus_k, two_p_minus_k; /* 2^(k-1) + 2^(-k-1) */
349
+ double square_y_hi;
350
+
351
+ /* Now we can do the first range reduction*/
352
+ DOUBLE2INT(k, x * inv_ln_2.d)
353
+ if (k != 0){ /* b_hi + b_lo = x - (ln2_hi + ln2_lo) * k */
354
+ temp_hi = x - ln2_hi.d * k;
355
+ temp_lo = -ln2_lo.d * k;
356
+ Add12Cond(b_hi, b_lo, temp_hi, temp_lo);
357
+ }
358
+ else {
359
+ b_hi = x; b_lo = 0.;
360
+ }
361
+
362
+ /*we'll construct 2 constants for the last reconstruction */
363
+ two_p_plus_k.i[LO] = 0;
364
+ two_p_plus_k.i[HI] = (k-1+1023) << 20;
365
+ two_p_minus_k.i[LO] = 0;
366
+ two_p_minus_k.i[HI] = (-k-1+1023) << 20;
367
+
368
+ /* at this stage, we've done the first range reduction : we have b_hi + b_lo between -ln(2)/2 and ln(2)/2 */
369
+ /* now we can do the second range reduction */
370
+ /* we'll get the 8 leading bits of r_hi */
371
+
372
+ table_index_float.d = b_hi + two_43_44.d;
373
+ /*this add do the float equivalent of a rotation to the right, since -0.5 <= b_hi <= 0.5*/
374
+ table_index = table_index_float.i[LO];/* -89 <= table_index <= 89 */
375
+ table_index_float.d -= two_43_44.d;
376
+ table_index += bias; /* to have only positive values */
377
+ b_hi -= table_index_float.d;/* to remove the 8 leading bits*/
378
+ /* since b_hi was between -2^-1 and 2^1, we now have b_hi between -2^-9 and 2^-9 */
379
+
380
+ y.d = b_hi;
381
+ /* first, y� = square_y_hi + square_y_lo */
382
+ square_y_hi = b_hi * b_hi;
383
+ /* effective computation of the polyomial approximation */
384
+ if (((y.i[HI])&(0x7FFFFFFF)) <= (two_minus_30.i[HI])) {
385
+ tsb_hi = 0;
386
+ tcb_hi = 0;
387
+ }
388
+ else {
389
+ tsb_hi = square_y_hi * (s3.d + square_y_hi * (s5.d + square_y_hi * s7.d));
390
+ /* second, cosh(y) = y� * (1/2 + y� * (1/24 + y� * 1/720)) */
391
+ tcb_hi = (square_y_hi)* (c2.d + square_y_hi * (c4.d + square_y_hi * c6.d));
392
+ }
393
+
394
+ if( table_index != bias) {
395
+ /* we get the tabulated the tabulated values*/
396
+ ca_hi = cosh_sinh_table[table_index][0].d;
397
+ ca_lo = cosh_sinh_table[table_index][1].d;
398
+ sa_hi = cosh_sinh_table[table_index][2].d;
399
+ sa_lo = cosh_sinh_table[table_index][3].d;
400
+
401
+ /* first reconstruction for the sinh (corresponding to the second range reduction) */
402
+ temp1 = sa_lo;
403
+ temp1 += b_lo * ca_hi;
404
+ temp1 += b_hi * ca_lo;
405
+ Mul12(&ca_b_hi, &ca_b_lo, ca_hi, b_hi);
406
+ temp1 += ca_b_lo;
407
+ temp1 += sa_hi * tcb_hi;
408
+ temp1 += ca_b_hi * tsb_hi;
409
+ Add12Cond(temp_hi, temp_lo, ca_b_hi, temp1);
410
+ Add22Cond(&sh_hi, &sh_lo, sa_hi, (double) 0, temp_hi, temp_lo);
411
+ /* first reconstruction of the cosh (corresponding to the second range reduction) */
412
+ temp1 = ca_lo;
413
+ Mul12(&sa_b_hi,&sa_b_lo, sa_hi, b_hi);
414
+ temp1 += b_hi * sa_lo;
415
+ temp1 += b_lo * sa_hi;
416
+ temp1 += sa_b_lo;
417
+ temp1 += sa_b_hi * tsb_hi;
418
+ temp1 += ca_hi * tcb_hi;
419
+ temp1 += sa_b_hi;
420
+ Add12Cond(ch_hi, ch_lo, ca_hi, temp1);
421
+ }
422
+ else {
423
+ Add12Cond(sh_hi, sh_lo, b_hi, tsb_hi * b_hi + b_lo);
424
+ Add12Cond(ch_hi, ch_lo, (double) 1, tcb_hi);
425
+ }
426
+
427
+ if(k != 0) {
428
+ if( (k < 35) && (k > -35) ) {
429
+ ch_2_pk_hi = ch_hi * two_p_plus_k.d;
430
+ ch_2_pk_lo = ch_lo * two_p_plus_k.d;
431
+ ch_2_mk_hi = - ch_hi * two_p_minus_k.d;
432
+ ch_2_mk_lo = - ch_lo * two_p_minus_k.d;
433
+ sh_2_pk_hi = sh_hi * two_p_plus_k.d;
434
+ sh_2_pk_lo = sh_lo * two_p_plus_k.d;
435
+ sh_2_mk_hi = sh_hi * two_p_minus_k.d;
436
+ sh_2_mk_lo = sh_lo * two_p_minus_k.d;
437
+
438
+ Add22Cond(prh, prl, ch_2_mk_hi, ch_2_mk_lo, sh_2_mk_hi, sh_2_mk_lo);
439
+ Add22Cond(&ch_2_mk_hi, &ch_2_mk_lo , sh_2_pk_hi, sh_2_pk_lo, *prh, *prl);
440
+ Add22Cond(prh, prl, ch_2_pk_hi, ch_2_pk_lo, ch_2_mk_hi, ch_2_mk_lo);
441
+ }
442
+ else if (k >= 35)
443
+ {
444
+ ch_2_pk_hi = ch_hi * two_p_plus_k.d;
445
+ ch_2_pk_lo = ch_lo * two_p_plus_k.d;
446
+ sh_2_pk_hi = sh_hi * two_p_plus_k.d;
447
+ sh_2_pk_lo = sh_lo * two_p_plus_k.d;
448
+ Add22Cond(prh, prl, ch_2_pk_hi, ch_2_pk_lo, sh_2_pk_hi, sh_2_pk_lo);
449
+ }
450
+ else
451
+ {
452
+ ch_2_mk_hi = - ch_hi * two_p_minus_k.d;
453
+ ch_2_mk_lo = - ch_lo * two_p_minus_k.d;
454
+ sh_2_mk_hi = sh_hi * two_p_minus_k.d;
455
+ sh_2_mk_lo = sh_lo * two_p_minus_k.d;
456
+ Add22Cond(prh, prl, ch_2_mk_hi, ch_2_mk_lo, sh_2_mk_hi, sh_2_mk_lo);
457
+ }
458
+ }
459
+ else {
460
+ *prh = sh_hi;
461
+ *prl = sh_lo;
462
+ }
463
+ }
464
+
465
+
466
+
467
+
468
+
469
+ static void do_sinh_accurate(double x, scs_ptr res_scs){
470
+ int k;
471
+ scs_t exp_scs, exp_minus_scs;
472
+
473
+ #if EVAL_PERF==1
474
+ crlibm_second_step_taken++;
475
+ #endif
476
+ /* we'll use the sinh(x) == (exp(x) - 1/exp(x))/2 */
477
+ DOUBLE2INT(k, x * inv_ln_2.d);
478
+ if ((k > -65) && (k < 65)) {
479
+ exp_SC(exp_scs, x);
480
+ scs_inv(exp_minus_scs, exp_scs);
481
+ scs_sub(res_scs, exp_scs, exp_minus_scs);
482
+ scs_div_2(res_scs);
483
+ }
484
+ else if (k >= 65) {
485
+ exp_SC(res_scs, x);
486
+ scs_div_2(res_scs);
487
+ }
488
+ else {
489
+ exp_SC(res_scs, -x);
490
+ res_scs->sign = -1;
491
+ scs_div_2(res_scs);
492
+ }
493
+ }
494
+
495
+
496
+
497
+ double sinh_rn(double x){
498
+ db_number y;
499
+ int hx;
500
+ double rh, rl;
501
+ scs_t res_scs;
502
+
503
+
504
+ y.d = x;
505
+ hx = y.i[HI] & 0x7FFFFFFF;
506
+
507
+ /* Filter special cases */
508
+ if (hx > max_input_csh.i[HI]) { /* strictly greater, implies x > max_input_csh */
509
+ if (hx >= 0x7ff00000){ /* infinity or NaN */
510
+ if (((hx&0x000fffff)|y.i[LO])!=0)
511
+ return x+x; /* NaN */
512
+ else {/* otherwise the result should be +infty */
513
+ return (y.d);
514
+ }
515
+ }
516
+ if (x > max_input_csh.d)
517
+ return largest_double * largest_double; /* overflow */
518
+ if (x < -max_input_csh.d)
519
+ return -largest_double * largest_double; /* overflow */
520
+ }
521
+
522
+ if (hx<0x3e500000) {
523
+ return x; /* exact, we should find some way of raising the inexact flag */
524
+ }
525
+
526
+
527
+ do_sinh(x, &rh, &rl);
528
+
529
+ if (rh == (rh + (rl * round_cst_csh))) return rh;
530
+ else{
531
+ do_sinh_accurate(x, res_scs);
532
+ scs_get_d(&rh, res_scs);
533
+ return rh;
534
+ }
535
+
536
+ }
537
+
538
+
539
+
540
+ double sinh_ru(double x){
541
+ db_number y;
542
+ double rh, rl;
543
+ scs_t res_scs;
544
+
545
+
546
+ y.d = x;
547
+ y.i[HI] = y.i[HI] & 0x7FFFFFFF; /* to get the absolute value of the input */
548
+ if ((y.i[HI] & 0x7FF00000) >= (0x7FF00000)) { /*particular cases : QNaN, SNaN, +- oo*/
549
+ return (x);
550
+ }
551
+ if (y.d > max_input_csh.d) { /* out of range */
552
+ if(x>0) {
553
+ y.i[LO] = 0; y.i[HI] = 0x7FF00000; return (y.d);
554
+ }
555
+ else {
556
+ y.i[LO] = 0xFFFFFFFF; y.i[HI] = 0xFFEFFFFF ; return (y.d);
557
+ }
558
+ }
559
+
560
+ if(y.i[HI] < 0x3e500000) /* 2^(-26) */
561
+ { /* Add one ulp if x positive */
562
+ if(x>0) {
563
+ y.l++;
564
+ return y.d;
565
+ }
566
+ else
567
+ return x;
568
+ }
569
+
570
+ do_sinh(x, &rh, &rl);
571
+
572
+ TEST_AND_RETURN_RU(rh, rl, maxepsilon_csh);
573
+
574
+ /* if the previous block didn't return a value, launch accurate phase */
575
+ do_sinh_accurate(x, res_scs);
576
+ scs_get_d_pinf(&rh, res_scs);
577
+ return rh;
578
+ }
579
+
580
+
581
+ double sinh_rd(double x){
582
+ db_number y;
583
+ double rh, rl;
584
+ scs_t res_scs;
585
+
586
+
587
+ y.d = x;
588
+ y.i[HI] = y.i[HI] & 0x7FFFFFFF; /* to get the absolute value of the input */
589
+ if ((y.i[HI] & 0x7FF00000) >= (0x7FF00000)) { /*particular cases : QNaN, SNaN, +- oo*/
590
+ y.d = x;
591
+ return (y.d);
592
+ }
593
+ if (y.d > max_input_csh.d) { /* out of range */
594
+ if(x>0) {
595
+ y.i[LO] = 0xFFFFFFFF; y.i[HI] = 0x7FEFFFFF ; return (y.d);
596
+ }
597
+ else {
598
+ y.i[LO] = 0; y.i[HI] = 0xFFF00000; return (y.d);
599
+ }
600
+ }
601
+ if(y.i[HI] < 0x3e500000) /* 2^(-26) */
602
+ { /* Add one ulp and restore the sign if x negative */
603
+ if(x<0){
604
+ y.l = (y.l+1);
605
+ return -y.d;
606
+ }
607
+ else
608
+ return x;
609
+ }
610
+ do_sinh(x, &rh, &rl);
611
+
612
+ TEST_AND_RETURN_RD(rh, rl, maxepsilon_csh);
613
+
614
+ /* if the previous block didn't return a value, launch accurate phase */
615
+ do_sinh_accurate(x, res_scs);
616
+ scs_get_d_minf(&rh, res_scs);
617
+ return rh;
618
+ }
619
+
620
+
621
+
622
+
623
+ double sinh_rz(double x){
624
+ if( x > 0) {
625
+ return(sinh_rd(x));
626
+ }
627
+ else {
628
+ return(sinh_ru(x));
629
+ }
630
+ }
631
+