crmf 0.1.1 → 0.1.3

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 (111) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +12 -0
  3. data/crmf.gemspec +105 -3
  4. data/ext/crlibm-1.0beta5/AUTHORS +2 -0
  5. data/ext/crlibm-1.0beta5/CMakeLists.txt +154 -0
  6. data/ext/crlibm-1.0beta5/COPYING +340 -0
  7. data/ext/crlibm-1.0beta5/COPYING.LIB +504 -0
  8. data/ext/crlibm-1.0beta5/ChangeLog +125 -0
  9. data/ext/crlibm-1.0beta5/Makefile.am +134 -0
  10. data/ext/crlibm-1.0beta5/NEWS +0 -0
  11. data/ext/crlibm-1.0beta5/README +31 -0
  12. data/ext/crlibm-1.0beta5/README.DEV +23 -0
  13. data/ext/crlibm-1.0beta5/README.md +5 -0
  14. data/ext/crlibm-1.0beta5/TODO +66 -0
  15. data/ext/crlibm-1.0beta5/VERSION +1 -0
  16. data/ext/crlibm-1.0beta5/acos-td.c +1195 -0
  17. data/ext/crlibm-1.0beta5/acos-td.h +629 -0
  18. data/ext/crlibm-1.0beta5/asin-td.c +1297 -0
  19. data/ext/crlibm-1.0beta5/asin-td.h +620 -0
  20. data/ext/crlibm-1.0beta5/asincos.c +4488 -0
  21. data/ext/crlibm-1.0beta5/asincos.h +575 -0
  22. data/ext/crlibm-1.0beta5/atan-itanium.c +846 -0
  23. data/ext/crlibm-1.0beta5/atan-pentium.c +280 -0
  24. data/ext/crlibm-1.0beta5/atan-pentium.h +343 -0
  25. data/ext/crlibm-1.0beta5/atan_accurate.c +341 -0
  26. data/ext/crlibm-1.0beta5/atan_accurate.h +198 -0
  27. data/ext/crlibm-1.0beta5/atan_fast.c +506 -0
  28. data/ext/crlibm-1.0beta5/atan_fast.h +680 -0
  29. data/ext/crlibm-1.0beta5/configure.ac +419 -0
  30. data/ext/crlibm-1.0beta5/crlibm.h +204 -0
  31. data/ext/crlibm-1.0beta5/crlibm.spec +42 -0
  32. data/ext/crlibm-1.0beta5/crlibm_private.c +397 -0
  33. data/ext/crlibm-1.0beta5/crlibm_private.h +1048 -0
  34. data/ext/crlibm-1.0beta5/csh_fast.c +721 -0
  35. data/ext/crlibm-1.0beta5/csh_fast.h +771 -0
  36. data/ext/crlibm-1.0beta5/double-extended.h +496 -0
  37. data/ext/crlibm-1.0beta5/exp-itanium.c +723 -0
  38. data/ext/crlibm-1.0beta5/exp-td-standalone.c +87 -0
  39. data/ext/crlibm-1.0beta5/exp-td.c +1363 -0
  40. data/ext/crlibm-1.0beta5/exp-td.h +685 -0
  41. data/ext/crlibm-1.0beta5/exp_build_coeffs/exp_fast_table.c +125 -0
  42. data/ext/crlibm-1.0beta5/expm1-standalone.c +119 -0
  43. data/ext/crlibm-1.0beta5/expm1.c +2515 -0
  44. data/ext/crlibm-1.0beta5/expm1.h +715 -0
  45. data/ext/crlibm-1.0beta5/interval.h +238 -0
  46. data/ext/crlibm-1.0beta5/log-de.c +480 -0
  47. data/ext/crlibm-1.0beta5/log-de.h +747 -0
  48. data/ext/crlibm-1.0beta5/log-de2.c +280 -0
  49. data/ext/crlibm-1.0beta5/log-de2.h +2352 -0
  50. data/ext/crlibm-1.0beta5/log-td.c +1158 -0
  51. data/ext/crlibm-1.0beta5/log-td.h +819 -0
  52. data/ext/crlibm-1.0beta5/log.c +2244 -0
  53. data/ext/crlibm-1.0beta5/log.h +1592 -0
  54. data/ext/crlibm-1.0beta5/log10-td.c +906 -0
  55. data/ext/crlibm-1.0beta5/log10-td.h +823 -0
  56. data/ext/crlibm-1.0beta5/log1p.c +1295 -0
  57. data/ext/crlibm-1.0beta5/log2-td.c +1521 -0
  58. data/ext/crlibm-1.0beta5/log2-td.h +821 -0
  59. data/ext/crlibm-1.0beta5/log2_accurate.c +330 -0
  60. data/ext/crlibm-1.0beta5/log2_accurate.h +261 -0
  61. data/ext/crlibm-1.0beta5/log_accurate.c +133 -0
  62. data/ext/crlibm-1.0beta5/log_accurate.h +261 -0
  63. data/ext/crlibm-1.0beta5/log_fast.c +360 -0
  64. data/ext/crlibm-1.0beta5/log_fast.h +440 -0
  65. data/ext/crlibm-1.0beta5/pow.c +1396 -0
  66. data/ext/crlibm-1.0beta5/pow.h +3101 -0
  67. data/ext/crlibm-1.0beta5/prepare +20 -0
  68. data/ext/crlibm-1.0beta5/rem_pio2_accurate.c +219 -0
  69. data/ext/crlibm-1.0beta5/rem_pio2_accurate.h +53 -0
  70. data/ext/crlibm-1.0beta5/scs_lib/AUTHORS +3 -0
  71. data/ext/crlibm-1.0beta5/scs_lib/COPYING +504 -0
  72. data/ext/crlibm-1.0beta5/scs_lib/ChangeLog +16 -0
  73. data/ext/crlibm-1.0beta5/scs_lib/Doxyfile.dev +939 -0
  74. data/ext/crlibm-1.0beta5/scs_lib/Doxyfile.user +939 -0
  75. data/ext/crlibm-1.0beta5/scs_lib/INSTALL +215 -0
  76. data/ext/crlibm-1.0beta5/scs_lib/Makefile.am +17 -0
  77. data/ext/crlibm-1.0beta5/scs_lib/NEWS +0 -0
  78. data/ext/crlibm-1.0beta5/scs_lib/README +9 -0
  79. data/ext/crlibm-1.0beta5/scs_lib/README.DEV +38 -0
  80. data/ext/crlibm-1.0beta5/scs_lib/TODO +4 -0
  81. data/ext/crlibm-1.0beta5/scs_lib/VERSION +1 -0
  82. data/ext/crlibm-1.0beta5/scs_lib/addition_scs.c +623 -0
  83. data/ext/crlibm-1.0beta5/scs_lib/division_scs.c +110 -0
  84. data/ext/crlibm-1.0beta5/scs_lib/double2scs.c +174 -0
  85. data/ext/crlibm-1.0beta5/scs_lib/main.dox +104 -0
  86. data/ext/crlibm-1.0beta5/scs_lib/multiplication_scs.c +339 -0
  87. data/ext/crlibm-1.0beta5/scs_lib/poly_fct.c +112 -0
  88. data/ext/crlibm-1.0beta5/scs_lib/print_scs.c +73 -0
  89. data/ext/crlibm-1.0beta5/scs_lib/rand_scs.c +63 -0
  90. data/ext/crlibm-1.0beta5/scs_lib/scs.h +353 -0
  91. data/ext/crlibm-1.0beta5/scs_lib/scs2double.c +411 -0
  92. data/ext/crlibm-1.0beta5/scs_lib/scs2mpf.c +58 -0
  93. data/ext/crlibm-1.0beta5/scs_lib/scs2mpfr.c +61 -0
  94. data/ext/crlibm-1.0beta5/scs_lib/scs_private.c +23 -0
  95. data/ext/crlibm-1.0beta5/scs_lib/scs_private.h +133 -0
  96. data/ext/crlibm-1.0beta5/scs_lib/wrapper_scs.h +486 -0
  97. data/ext/crlibm-1.0beta5/scs_lib/zero_scs.c +52 -0
  98. data/ext/crlibm-1.0beta5/trigo_accurate.c +501 -0
  99. data/ext/crlibm-1.0beta5/trigo_accurate.h +331 -0
  100. data/ext/crlibm-1.0beta5/trigo_fast.c +1243 -0
  101. data/ext/crlibm-1.0beta5/trigo_fast.h +639 -0
  102. data/ext/crlibm-1.0beta5/trigpi.c +1169 -0
  103. data/ext/crlibm-1.0beta5/trigpi.h +556 -0
  104. data/ext/crlibm-1.0beta5/triple-double.c +57 -0
  105. data/ext/crlibm-1.0beta5/triple-double.h +1380 -0
  106. data/ext/crmf/crmf.c +117 -20
  107. data/ext/crmf/extconf.rb +12 -8
  108. data/lib/crmf/version.rb +1 -1
  109. data/tests/perf.rb +100 -219
  110. metadata +108 -10
  111. data/ext/crlibm-1.0beta4.tar.gz +0 -0
@@ -0,0 +1,721 @@
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
+
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
+
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
+
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
+
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
+
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
+
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
+
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
+
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
+
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
+
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
+
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
+
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
+