intervals 0.3.56

Sign up to get free protection for your applications and to get access to all the features.
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
+