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,2515 @@
1
+ /*
2
+ * Correctly rounded expm1 = e^x - 1
3
+ *
4
+ * Author : Christoph Lauter (ENS Lyon)
5
+ * One bug fix by Florent de Dinechin
6
+ *
7
+ * This file is part of the crlibm library developed by the Arenaire
8
+ * project at Ecole Normale Superieure de Lyon
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 "triple-double.h"
30
+ #include "expm1.h"
31
+ #ifdef BUILD_INTERVAL_FUNCTIONS
32
+ #include "interval.h"
33
+ #endif
34
+
35
+
36
+
37
+ #define DEBUG 0
38
+
39
+
40
+ void expm1_direct_td(double *expm1h, double *expm1m, double *expm1l,
41
+ double x, double xSqHalfh, double xSqHalfl, double xSqh, double xSql, int expoX) {
42
+ double highPoly, tt1h, t1h, t1l, t2h, t2l, t3h, t3l, t4h, t4l, t5h, t5l, t6h, t6l;
43
+ double tt6h, tt6m, tt6l, t7h, t7m, t7l, lowPolyh, lowPolym, lowPolyl;
44
+ double fullHighPolyh, fullHighPolym, fullHighPolyl, polyh, polym, polyl;
45
+ double xCubeh, xCubem, xCubel, tt7h, tt7m, tt7l, t8h, t8m, t8l;
46
+ double expm1hover, expm1mover, expm1lover;
47
+ double r1h, r1m, r1l, r2h, r2m, r2l, r3h, r3m, r3l;
48
+ double rr1h, rr1m, rr1l, rr2h, rr2m, rr2l, rr3h, rr3m, rr3l;
49
+ double fullHighPolyhover, fullHighPolymover, fullHighPolylover;
50
+
51
+ /* Double precision evaluation steps */
52
+ #if defined(PROCESSOR_HAS_FMA) && !defined(AVOID_FMA)
53
+ highPoly = FMA(FMA(FMA(FMA(accuDirectpolyC15h ,x,accuDirectpolyC14h),x,accuDirectpolyC13h),x,
54
+ accuDirectpolyC12h),x,accuDirectpolyC11h);
55
+ #else
56
+ highPoly = accuDirectpolyC11h + x * (accuDirectpolyC12h + x * (accuDirectpolyC13h + x * (
57
+ accuDirectpolyC14h + x * accuDirectpolyC15h)));
58
+ #endif
59
+
60
+ tt1h = x * highPoly;
61
+
62
+ /* Triple-double steps for x + x^2/2 and x^3*/
63
+
64
+ Add123(&lowPolyh,&lowPolym,&lowPolyl,x,xSqHalfh,xSqHalfl); /* infty - 52/53 */
65
+ Mul123(&xCubeh,&xCubem,&xCubel,x,xSqh,xSql); /* 154 - 47/53 */
66
+
67
+
68
+ /* Double-double evaluation steps */
69
+
70
+ Add12(t1h,t1l,accuDirectpolyC10h,tt1h);
71
+
72
+ MulAdd212(&t2h,&t2l,accuDirectpolyC9h,accuDirectpolyC9m,x,t1h,t1l);
73
+ MulAdd212(&t3h,&t3l,accuDirectpolyC8h,accuDirectpolyC8m,x,t2h,t2l);
74
+ MulAdd212(&t4h,&t4l,accuDirectpolyC7h,accuDirectpolyC7m,x,t3h,t3l);
75
+ MulAdd212(&t5h,&t5l,accuDirectpolyC6h,accuDirectpolyC6m,x,t4h,t4l);
76
+ MulAdd212(&t6h,&t6l,accuDirectpolyC5h,accuDirectpolyC5m,x,t5h,t5l);
77
+
78
+ /* Triple-double evaluation steps */
79
+
80
+ Mul123(&tt6h,&tt6m,&tt6l,x,t6h,t6l); /* 154 - 47/53 */
81
+ Add233(&t7h,&t7m,&t7l,accuDirectpolyC4h,accuDirectpolyC4m,tt6h,tt6m,tt6l); /* 150 - 43/53 */
82
+
83
+ Mul133(&tt7h,&tt7m,&tt7l,x,t7h,t7m,t7l); /* 143 - 38/53 */
84
+ Add33(&t8h,&t8m,&t8l,accuDirectpolyC3h,accuDirectpolyC3m,accuDirectpolyC3l,tt7h,tt7m,tt7l); /* 135 - 33/53 */
85
+
86
+ Mul33(&fullHighPolyhover,&fullHighPolymover,&fullHighPolylover,xCubeh,xCubem,xCubel,t8h,t8m,t8l); /* 130 - 29/53 */
87
+
88
+ Renormalize3(&fullHighPolyh,&fullHighPolym,&fullHighPolyl,
89
+ fullHighPolyhover,fullHighPolymover,fullHighPolylover); /* infty - 52/53 */
90
+
91
+ Add33(&polyh,&polym,&polyl,lowPolyh,lowPolym,lowPolyl,fullHighPolyh,fullHighPolym,fullHighPolyl);
92
+ /* 149 - 47/53 */
93
+
94
+ /* Reconstruction steps */
95
+
96
+ /* If we have not performed any range reduction, we have no reconstruction to do */
97
+ if (expoX >= 0) {
98
+ /* If we are here, we must perform reconstruction */
99
+
100
+ /* First reconstruction step */
101
+
102
+ Add133(&r1h,&r1m,&r1l,2,polyh,polym,polyl);
103
+ Mul33(&rr1h,&rr1m,&rr1l,r1h,r1m,r1l,polyh,polym,polyl);
104
+ if (expoX >= 1) {
105
+
106
+ /* Second reconstruction step */
107
+ Add133(&r2h,&r2m,&r2l,2,rr1h,rr1m,rr1l);
108
+ Mul33(&rr2h,&rr2m,&rr2l,r2h,r2m,r2l,rr1h,rr1m,rr1l);
109
+
110
+ if (expoX >= 2) {
111
+
112
+ /* Third reconstruction step */
113
+ Add133(&r3h,&r3m,&r3l,2,rr2h,rr2m,rr2l);
114
+ Mul33(&rr3h,&rr3m,&rr3l,r3h,r3m,r3l,rr2h,rr2m,rr2l);
115
+
116
+ /* expoX may be maximally 2 */
117
+
118
+ expm1hover = rr3h;
119
+ expm1mover = rr3m;
120
+ expm1lover = rr3l;
121
+
122
+ } else {
123
+ expm1hover = rr2h;
124
+ expm1mover = rr2m;
125
+ expm1lover = rr2l;
126
+ }
127
+
128
+ } else {
129
+ expm1hover = rr1h;
130
+ expm1mover = rr1m;
131
+ expm1lover = rr1l;
132
+ }
133
+
134
+ } else {
135
+ expm1hover = polyh;
136
+ expm1mover = polym;
137
+ expm1lover = polyl;
138
+ }
139
+
140
+ /* Renormalize before returning */
141
+
142
+ Renormalize3(expm1h,expm1m,expm1l,expm1hover,expm1mover,expm1lover);
143
+ }
144
+
145
+ void expm1_common_td(double *expm1h, double *expm1m, double *expm1l,
146
+ double rh, double rm, double rl,
147
+ double tbl1h, double tbl1m, double tbl1l,
148
+ double tbl2h, double tbl2m, double tbl2l,
149
+ int M) {
150
+ double highPoly, highPolyMulth, highPolyMultm, highPolyMultl;
151
+ double rhSquareh, rhSquarel, rhSquareHalfh, rhSquareHalfl;
152
+ double rhCubeh, rhCubem, rhCubel;
153
+ double t1h, t1l, t2h, t2l, t3h, t3l, t4h, t4l, t5, t6;
154
+ double lowPolyh, lowPolym, lowPolyl;
155
+ double ph, pm, pl, phnorm, pmnorm, rmlMultPh, rmlMultPl;
156
+ double qh, ql, fullPolyh, fullPolym, fullPolyl;
157
+ double polyWithTbl1h, polyWithTbl1m, polyWithTbl1l;
158
+ double polyAddOneh,polyAddOnem,polyAddOnel;
159
+ double polyWithTablesh, polyWithTablesm, polyWithTablesl;
160
+ double exph, expm, expl, expm1hover, expm1mover, expm1lover;
161
+ db_number polyWithTableshdb, polyWithTablesmdb, polyWithTablesldb;
162
+
163
+ /* Polynomial approximation - double precision steps */
164
+
165
+ #if defined(PROCESSOR_HAS_FMA) && !defined(AVOID_FMA)
166
+ highPoly = FMA(FMA(accuCommonpolyC7h,rh,accuCommonpolyC6h),rh,accuCommonpolyC5h);
167
+ #else
168
+ highPoly = accuCommonpolyC5h + rh * (accuCommonpolyC6h + rh * accuCommonpolyC7h);
169
+ #endif
170
+
171
+ /* Polynomial approximation - double-double precision steps */
172
+
173
+ Mul12(&t1h,&t1l,rh,highPoly);
174
+ Add22(&t2h,&t2l,accuCommonpolyC4h,accuCommonpolyC4m,t1h,t1l);
175
+ Mul122(&t3h,&t3l,rh,t2h,t2l);
176
+ Add22(&t4h,&t4l,accuCommonpolyC3h,accuCommonpolyC3m,t3h,t3l);
177
+
178
+ Mul12(&rhSquareh,&rhSquarel,rh,rh);
179
+ Mul123(&rhCubeh,&rhCubem,&rhCubel,rh,rhSquareh,rhSquarel);
180
+
181
+ rhSquareHalfh = 0.5 * rhSquareh;
182
+ rhSquareHalfl = 0.5 * rhSquarel;
183
+
184
+ /* Polynomial approximation - triple-double precision steps */
185
+
186
+ Renormalize3(&lowPolyh,&lowPolym,&lowPolyl,rh,rhSquareHalfh,rhSquareHalfl);
187
+
188
+ Mul233(&highPolyMulth,&highPolyMultm,&highPolyMultl,t4h,t4l,rhCubeh,rhCubem,rhCubel);
189
+
190
+ Add33(&ph,&pm,&pl,lowPolyh,lowPolym,lowPolyl,highPolyMulth,highPolyMultm,highPolyMultl);
191
+
192
+ /* Reconstruction */
193
+
194
+ Add12(phnorm,pmnorm,ph,pm);
195
+ Mul22(&rmlMultPh,&rmlMultPl,rm,rl,phnorm,pmnorm);
196
+ Add22(&qh,&ql,rm,rl,rmlMultPh,rmlMultPl);
197
+
198
+ Add233Cond(&fullPolyh,&fullPolym,&fullPolyl,qh,ql,ph,pm,pl);
199
+ Add12(polyAddOneh,t5,1,fullPolyh);
200
+ Add12Cond(polyAddOnem,t6,t5,fullPolym);
201
+ polyAddOnel = t6 + fullPolyl;
202
+ Mul33(&polyWithTbl1h,&polyWithTbl1m,&polyWithTbl1l,tbl1h,tbl1m,tbl1l,polyAddOneh,polyAddOnem,polyAddOnel);
203
+ Mul33(&polyWithTablesh,&polyWithTablesm,&polyWithTablesl,
204
+ tbl2h,tbl2m,tbl2l,
205
+ polyWithTbl1h,polyWithTbl1m,polyWithTbl1l);
206
+
207
+ /* Multiplication by 2^(M)
208
+
209
+ We perform it in integer to overcome the non-representability of 2^(1024)
210
+ This case is possible for M = 1024 and polyWithTablesh < 1
211
+
212
+ The overlap in the triple-double polyWithTables[hml] stays unchanged.
213
+
214
+ */
215
+
216
+ polyWithTableshdb.d = polyWithTablesh;
217
+ polyWithTablesmdb.d = polyWithTablesm;
218
+ polyWithTablesldb.d = polyWithTablesl;
219
+
220
+ /* TODO FIXME probably at least the first of these tests is useless,
221
+ but I leave this to Christoph to check it. Let us be
222
+ conservative. Florent */
223
+ if(polyWithTableshdb.d!=0)
224
+ polyWithTableshdb.i[HI] += M << 20;
225
+ if(polyWithTablesmdb.d!=0)
226
+ polyWithTablesmdb.i[HI] += M << 20;
227
+ if(polyWithTablesldb.d!=0)
228
+ polyWithTablesldb.i[HI] += M << 20;
229
+
230
+ exph = polyWithTableshdb.d;
231
+ expm = polyWithTablesmdb.d;
232
+ expl = polyWithTablesldb.d;
233
+
234
+ /* Subtraction of -1
235
+
236
+ We use a conditional Add133
237
+ */
238
+
239
+ Add133Cond(&expm1hover,&expm1mover,&expm1lover,-1,exph,expm,expl);
240
+
241
+ /* Renormalization */
242
+
243
+ Renormalize3(expm1h,expm1m,expm1l,expm1hover,expm1mover,expm1lover);
244
+
245
+ }
246
+
247
+
248
+ double expm1_rn(double x) {
249
+ db_number xdb, shiftedXMultdb, polyTblhdb, polyTblmdb;
250
+ int xIntHi, expoX, k, M, index1, index2;
251
+ double highPoly, tt1h, t1h, t1l, xSqh, xSql, xSqHalfh, xSqHalfl, xCubeh, xCubel, t2h, t2l, templ, tt3h, tt3l;
252
+ double polyh, polyl, expm1h, expm1m, expm1l;
253
+ double r1h, r1l, r1t, rr1h, rr1l;
254
+ double r2h, r2l, r2t, rr2h, rr2l;
255
+ double r3h, r3l, r3t, rr3h, rr3l;
256
+ double xMultLog2InvMult2L, shiftedXMult, kd, s1, s2, s3, s4, s5, rh, rm, rl;
257
+ double rhSquare, rhC3, rhSquareHalf, monomialCube, rhFour, monomialFour;
258
+ double tbl1h, tbl1m, tbl1l, tbl2h, tbl2m, tbl2l;
259
+ double highPolyWithSquare, tablesh, tablesl, t8, t9, t10, t11, t12, t13;
260
+ double exph, expm, t1, t2, t3;
261
+ double msLog2Div2LMultKh, msLog2Div2LMultKm, msLog2Div2LMultKl;
262
+ double middlePoly, doublePoly;
263
+
264
+
265
+ xdb.d = x;
266
+
267
+ /* Strip off the sign of x for the following tests */
268
+
269
+ xIntHi = xdb.i[HI] & 0x7fffffff;
270
+
271
+ /* Test if we are so small that we can return (a corrected) x as correct rounding */
272
+ if (xIntHi < RETURNXBOUND) {
273
+ return x;
274
+ }
275
+
276
+
277
+ /* Filter out special cases like overflow, -1 in result, infinities and NaNs
278
+ The filters are not sharp, we have positive arguments that flow through
279
+ */
280
+ if (xIntHi >= SIMPLEOVERFLOWBOUND) {
281
+ /* Test if we are +/-inf or NaN */
282
+ if (xIntHi >= 0x7ff00000) {
283
+ /* Test if NaN */
284
+ if (((xIntHi & 0x000fffff) | xdb.i[LO]) != 0) {
285
+ /* NaN */
286
+ return x+x; /* return NaN */
287
+ }
288
+ /* Test if +inf or -inf */
289
+ if (xdb.i[HI] > 0) {
290
+ /* +inf */
291
+ return x+x; /* return +inf */
292
+ }
293
+
294
+ /* If we are here, we are -inf */
295
+ return -1.0;
296
+ }
297
+
298
+ /* If we are here, we are overflowed or a common case that flows through */
299
+
300
+ /* Test if we are actually overflowed */
301
+ if (x > OVERFLOWBOUND) {
302
+ return LARGEST * LARGEST; /* return +inf and set flag */
303
+ }
304
+ }
305
+
306
+ /* Test if we know already that we are -1.0 (+ correction depending on rounding mode) in result */
307
+ if (x < MINUSONEBOUND) {
308
+ return -1.0;
309
+ }
310
+
311
+ /* Test if we have |x| <= 1/4-1/2ulp(1/4) for knowing if we use exp(x) or approximate directly */
312
+
313
+ if (xIntHi < DIRECTINTERVALBOUND) {
314
+ /* We approximate expm1 directly after a range reduction as follows
315
+
316
+ expm1(x) = (expm1(x/2) + 2) * expm1(x/2)
317
+
318
+ We perform the range reduction in such a way that finally |x| < 1/32
319
+ */
320
+
321
+ /* Extract the exponent of |x| and add 5 (2^5 = 32) */
322
+ expoX = ((xIntHi & 0x7ff00000) >> 20) - (1023 - 5);
323
+
324
+ /* If this particularily biased exponent expoX is negative, we are already less than 1/32 */
325
+ if (expoX >= 0) {
326
+ /* If we are here, we must perform range reduction */
327
+
328
+
329
+ /* We multiply x by 2^(-expoX-1) by bit manipulation
330
+ x cannot be denormalized so there is no danger
331
+ */
332
+ xdb.i[HI] += (-expoX-1) << 20;
333
+
334
+ /* We reassign the new x and maintain xIntHi */
335
+
336
+ xIntHi = xdb.i[HI] & 0x7fffffff;
337
+ x = xdb.d;
338
+ }
339
+
340
+ /* Here, we have always |x| < 1/32 */
341
+
342
+
343
+ /* Double precision evaluation steps and one double-double step */
344
+
345
+ Mul12(&xSqh,&xSql,x,x);
346
+
347
+ #if defined(PROCESSOR_HAS_FMA) && !defined(AVOID_FMA)
348
+ middlePoly = FMA(quickDirectpolyC5h,x,quickDirectpolyC4h);
349
+ #else
350
+ middlePoly = quickDirectpolyC4h + x * quickDirectpolyC5h;
351
+ #endif
352
+
353
+ doublePoly = middlePoly;
354
+
355
+ /* Special path: for small |x| we can truncate the polynomial */
356
+
357
+ if (xIntHi > SPECIALINTERVALBOUND) {
358
+
359
+ #if defined(PROCESSOR_HAS_FMA) && !defined(AVOID_FMA)
360
+ highPoly = FMA(FMA(FMA(quickDirectpolyC9h ,x,quickDirectpolyC8h),x,
361
+ quickDirectpolyC7h),x,quickDirectpolyC6h);
362
+ #else
363
+ highPoly = quickDirectpolyC6h + x * (quickDirectpolyC7h + x * (
364
+ quickDirectpolyC8h + x * quickDirectpolyC9h));
365
+ #endif
366
+
367
+ highPolyWithSquare = xSqh * highPoly;
368
+
369
+ doublePoly = middlePoly + highPolyWithSquare;
370
+
371
+ }
372
+
373
+ /* Double-double evaluation steps */
374
+ tt1h = x * doublePoly;
375
+
376
+ xSqHalfh = 0.5 * xSqh;
377
+ xSqHalfl = 0.5 * xSql;
378
+ Add12(t2h,templ,x,xSqHalfh);
379
+ t2l = templ + xSqHalfl;
380
+
381
+ Add12(t1h,t1l,quickDirectpolyC3h,tt1h);
382
+ Mul122(&xCubeh,&xCubel,x,xSqh,xSql);
383
+ Mul22(&tt3h,&tt3l,xCubeh,xCubel,t1h,t1l);
384
+
385
+ Add22(&polyh,&polyl,t2h,t2l,tt3h,tt3l);
386
+
387
+ /* Reconstruction */
388
+
389
+ /* If we have not performed any range reduction, we have no reconstruction to do */
390
+ if (expoX >= 0) {
391
+ /* If we are here, we must perform reconstruction */
392
+
393
+ /* First reconstruction step */
394
+ Add12(r1h,r1t,2,polyh);
395
+ r1l = r1t + polyl;
396
+ Mul22(&rr1h,&rr1l,r1h,r1l,polyh,polyl);
397
+
398
+ if (expoX >= 1) {
399
+
400
+ /* Second reconstruction step */
401
+ Add12(r2h,r2t,2,rr1h);
402
+ r2l = r2t + rr1l;
403
+ Mul22(&rr2h,&rr2l,r2h,r2l,rr1h,rr1l);
404
+
405
+ if (expoX >= 2) {
406
+
407
+ /* Third reconstruction step */
408
+ Add12(r3h,r3t,2,rr2h);
409
+ r3l = r3t + rr2l;
410
+ Mul22(&rr3h,&rr3l,r3h,r3l,rr2h,rr2l);
411
+
412
+ /* expoX may be maximally 2 */
413
+
414
+ expm1h = rr3h;
415
+ expm1m = rr3l;
416
+
417
+ } else {
418
+ expm1h = rr2h;
419
+ expm1m = rr2l;
420
+ }
421
+
422
+ } else {
423
+ expm1h = rr1h;
424
+ expm1m = rr1l;
425
+ }
426
+
427
+ } else {
428
+ expm1h = polyh;
429
+ expm1m = polyl;
430
+ }
431
+
432
+ /* Rounding test */
433
+ if(expm1h == (expm1h + (expm1m * ROUNDCSTDIRECTRN)))
434
+ return expm1h;
435
+ else
436
+ {
437
+
438
+ #if DEBUG
439
+ printf("Launch accurate phase (direct interval)\n");
440
+ #endif
441
+
442
+ expm1_direct_td(&expm1h, &expm1m, &expm1l, x, xSqHalfh, xSqHalfl, xSqh, xSql, expoX);
443
+
444
+ ReturnRoundToNearest3(expm1h, expm1m, expm1l);
445
+
446
+ } /* Accurate phase launched */
447
+
448
+ /* We cannot be here, since we return in all cases before */
449
+ }
450
+
451
+ /* If we are here, we can use expm1(x) = exp(x) - 1 */
452
+
453
+ /* Range reduction - exact part: compute k as double and as int */
454
+
455
+ xMultLog2InvMult2L = x * log2InvMult2L;
456
+ shiftedXMult = xMultLog2InvMult2L + shiftConst;
457
+ kd = shiftedXMult - shiftConst;
458
+ shiftedXMultdb.d = shiftedXMult;
459
+ k = shiftedXMultdb.i[LO];
460
+ M = k >> 12;
461
+ index1 = k & INDEXMASK1;
462
+ index2 = (k & INDEXMASK2) >> 6;
463
+
464
+ /* Range reduction - part affected by error - must be redone in accurate phase */
465
+ Mul12(&s1,&s2,msLog2Div2Lh,kd);
466
+ s3 = kd * msLog2Div2Lm;
467
+ s4 = s2 + s3;
468
+ s5 = x + s1;
469
+ Add12Cond(rh,rm,s5,s4);
470
+
471
+ /* Table reads - read only two double-doubles by now */
472
+ tbl1h = twoPowerIndex1[index1].hi;
473
+ tbl1m = twoPowerIndex1[index1].mi;
474
+ tbl2h = twoPowerIndex2[index2].hi;
475
+ tbl2m = twoPowerIndex2[index2].mi;
476
+
477
+ /* Quick phase starts here */
478
+
479
+ rhSquare = rh * rh;
480
+ rhC3 = quickCommonpolyC3h * rh;
481
+
482
+ rhSquareHalf = 0.5 * rhSquare;
483
+ monomialCube = rhC3 * rhSquare;
484
+ rhFour = rhSquare * rhSquare;
485
+
486
+ monomialFour = quickCommonpolyC4h * rhFour;
487
+
488
+ highPoly = monomialCube + monomialFour;
489
+
490
+ highPolyWithSquare = rhSquareHalf + highPoly;
491
+
492
+ /* Reconstruction: integration of table values */
493
+
494
+ Mul22(&tablesh,&tablesl,tbl1h,tbl1m,tbl2h,tbl2m);
495
+
496
+ t8 = rm + highPolyWithSquare;
497
+ t9 = rh + t8;
498
+
499
+ t10 = tablesh * t9;
500
+
501
+ Add12(t11,t12,tablesh,t10);
502
+ t13 = t12 + tablesl;
503
+ Add12(polyTblhdb.d,polyTblmdb.d,t11,t13);
504
+
505
+ /* Reconstruction: multiplication by 2^M */
506
+
507
+ /* Implement the multiplication by addition to overcome the
508
+ problem of the non-representability of 2^1024 (M = 1024)
509
+ This case is possible if polyTblhdb.d < 1
510
+ */
511
+
512
+ polyTblhdb.i[HI] += M << 20;
513
+ if(polyTblmdb.d!=0.0) /* predicted true, but it happens for x=-4.1588039009762204, thanks Morten */
514
+ polyTblmdb.i[HI] += M << 20;
515
+
516
+ exph = polyTblhdb.d;
517
+ expm = polyTblmdb.d;
518
+
519
+ /* Subtraction of 1
520
+
521
+ Testing if the operation is necessary is more expensive than
522
+ performing it in any case.
523
+
524
+ We may cancellate at most 2 bits in the subtraction for
525
+ arguments 1/4 <= x <= ln(2) (0.25 <= x <= 0.69)
526
+ We must therefore use conditional Add12s
527
+
528
+ Since we perform a subtraction, we may not have addition overflow towards +inf
529
+
530
+ */
531
+
532
+ Add12Cond(t1,t2,-1,exph);
533
+ t3 = t2 + expm;
534
+ Add12Cond(expm1h,expm1m,t1,t3);
535
+
536
+
537
+ /* Rounding test */
538
+ if(expm1h == (expm1h + (expm1m * ROUNDCSTCOMMONRN))) {
539
+ return expm1h;
540
+ } else {
541
+ /* Rest of argument reduction for accurate phase */
542
+
543
+ Mul133(&msLog2Div2LMultKh,&msLog2Div2LMultKm,&msLog2Div2LMultKl,kd,msLog2Div2Lh,msLog2Div2Lm,msLog2Div2Ll);
544
+ t1 = x + msLog2Div2LMultKh;
545
+ Add12Cond(rh,t2,t1,msLog2Div2LMultKm);
546
+ Add12Cond(rm,rl,t2,msLog2Div2LMultKl);
547
+
548
+ /* Table reads for accurate phase */
549
+ tbl1l = twoPowerIndex1[index1].lo;
550
+ tbl2l = twoPowerIndex2[index2].lo;
551
+
552
+ #if DEBUG
553
+ printf("Launch accurate phase (common interval)\n");
554
+ #endif
555
+
556
+ /* Call accurate phase */
557
+ expm1_common_td(&expm1h, &expm1m, &expm1l, rh, rm, rl, tbl1h, tbl1m, tbl1l, tbl2h, tbl2m, tbl2l, M);
558
+
559
+ /* Final rounding */
560
+
561
+ ReturnRoundToNearest3(expm1h, expm1m, expm1l);
562
+ } /* Accurate phase launched */
563
+
564
+ /* We cannot be here since we return before in any case */
565
+ }
566
+
567
+ double expm1_rd(double x) {
568
+ db_number xdb, shiftedXMultdb, polyTblhdb, polyTblmdb;
569
+ int xIntHi, expoX, k, M, index1, index2;
570
+ double highPoly, tt1h, t1h, t1l, xSqh, xSql, xSqHalfh, xSqHalfl, xCubeh, xCubel, t2h, t2l, templ, tt3h, tt3l;
571
+ double polyh, polyl, expm1h, expm1m, expm1l;
572
+ double r1h, r1l, r1t, rr1h, rr1l;
573
+ double r2h, r2l, r2t, rr2h, rr2l;
574
+ double r3h, r3l, r3t, rr3h, rr3l;
575
+ double xMultLog2InvMult2L, shiftedXMult, kd, s1, s2, s3, s4, s5, rh, rm, rl;
576
+ double rhSquare, rhC3, rhSquareHalf, monomialCube, rhFour, monomialFour;
577
+ double tbl1h, tbl1m, tbl1l, tbl2h, tbl2m, tbl2l;
578
+ double highPolyWithSquare, tablesh, tablesl, t8, t9, t10, t11, t12, t13;
579
+ double exph, expm, t1, t2, t3;
580
+ double msLog2Div2LMultKh, msLog2Div2LMultKm, msLog2Div2LMultKl;
581
+ double middlePoly, doublePoly;
582
+
583
+ xdb.d = x;
584
+
585
+ /* Strip off the sign of x for the following tests */
586
+
587
+ xIntHi = xdb.i[HI] & 0x7fffffff;
588
+
589
+ /* Test if we are so small that we can return (a corrected) x as correct rounding */
590
+ if (xIntHi < RETURNXBOUND) {
591
+ /* The only algebraic result is 0 for x = +/- 0; in this case, we can return x = +/- 0
592
+ The truncation rest x^2/2 + x^3/6 + ... is always positive
593
+ but less than 1 ulp in this case, so we round down by returning x
594
+ */
595
+ return x;
596
+ }
597
+
598
+
599
+ /* Filter out special cases like overflow, -1 in result, infinities and NaNs
600
+ The filters are not sharp, we have positive arguments that flow through
601
+ */
602
+ if (xIntHi >= SIMPLEOVERFLOWBOUND) {
603
+ /* Test if we are +/-inf or NaN */
604
+ if (xIntHi >= 0x7ff00000) {
605
+ /* Test if NaN */
606
+ if (((xIntHi & 0x000fffff) | xdb.i[LO]) != 0) {
607
+ /* NaN */
608
+ return x+x; /* return NaN */
609
+ }
610
+ /* Test if +inf or -inf */
611
+ if (xdb.i[HI] > 0) {
612
+ /* +inf */
613
+ return x+x; /* return +inf */
614
+ }
615
+
616
+ /* If we are here, we are -inf */
617
+ return -1.0;
618
+ }
619
+
620
+ /* If we are here, we are overflowed or a common case that flows through */
621
+
622
+ /* Test if we are actually overflowed */
623
+ if (x > OVERFLOWBOUND) {
624
+ /* We would be overflowed but as we are rounding downwards
625
+ the nearest number lesser than the exact result is the greatest
626
+ normal. In any case, we must raise the inexact flag.
627
+ */
628
+ return LARGEST * (1.0 + SMALLEST);
629
+ }
630
+ }
631
+
632
+ /* Test if we know already that we are -1.0 (+ correction depending on rounding mode) in result */
633
+ if (x < MINUSONEBOUND) {
634
+ /* We round down, so we are -1.0 */
635
+ return -1.0;
636
+ }
637
+
638
+ /* Test if we have |x| <= 1/4-1/2ulp(1/4) for knowing if we use exp(x) or approximate directly */
639
+
640
+ if (xIntHi < DIRECTINTERVALBOUND) {
641
+ /* We approximate expm1 directly after a range reduction as follows
642
+
643
+ expm1(x) = (expm1(x/2) + 2) * expm1(x/2)
644
+
645
+ We perform the range reduction in such a way that finally |x| < 1/32
646
+ */
647
+
648
+ /* Extract the exponent of |x| and add 5 (2^5 = 32) */
649
+ expoX = ((xIntHi & 0x7ff00000) >> 20) - (1023 - 5);
650
+
651
+ /* If this particularily biased exponent expoX is negative, we are already less than 1/32 */
652
+ if (expoX >= 0) {
653
+ /* If we are here, we must perform range reduction */
654
+
655
+
656
+ /* We multiply x by 2^(-expoX-1) by bit manipulation
657
+ x cannot be denormalized so there is no danger
658
+ */
659
+ xdb.i[HI] += (-expoX-1) << 20;
660
+
661
+ /* We reassign the new x and maintain xIntHi */
662
+
663
+ xIntHi = xdb.i[HI] & 0x7fffffff;
664
+ x = xdb.d;
665
+ }
666
+
667
+ /* Here, we have always |x| < 1/32 */
668
+
669
+
670
+ /* Double precision evaluation steps and one double-double step */
671
+
672
+ Mul12(&xSqh,&xSql,x,x);
673
+
674
+ #if defined(PROCESSOR_HAS_FMA) && !defined(AVOID_FMA)
675
+ middlePoly = FMA(quickDirectpolyC5h,x,quickDirectpolyC4h);
676
+ #else
677
+ middlePoly = quickDirectpolyC4h + x * quickDirectpolyC5h;
678
+ #endif
679
+
680
+ doublePoly = middlePoly;
681
+
682
+ /* Special path: for small |x| we can truncate the polynomial */
683
+
684
+ if (xIntHi > SPECIALINTERVALBOUND) {
685
+
686
+ #if defined(PROCESSOR_HAS_FMA) && !defined(AVOID_FMA)
687
+ highPoly = FMA(FMA(FMA(quickDirectpolyC9h ,x,quickDirectpolyC8h),x,
688
+ quickDirectpolyC7h),x,quickDirectpolyC6h);
689
+ #else
690
+ highPoly = quickDirectpolyC6h + x * (quickDirectpolyC7h + x * (
691
+ quickDirectpolyC8h + x * quickDirectpolyC9h));
692
+ #endif
693
+
694
+ highPolyWithSquare = xSqh * highPoly;
695
+
696
+ doublePoly = middlePoly + highPolyWithSquare;
697
+
698
+ }
699
+
700
+ /* Double-double evaluation steps */
701
+ tt1h = x * doublePoly;
702
+
703
+ xSqHalfh = 0.5 * xSqh;
704
+ xSqHalfl = 0.5 * xSql;
705
+ Add12(t2h,templ,x,xSqHalfh);
706
+ t2l = templ + xSqHalfl;
707
+
708
+ Add12(t1h,t1l,quickDirectpolyC3h,tt1h);
709
+ Mul122(&xCubeh,&xCubel,x,xSqh,xSql);
710
+ Mul22(&tt3h,&tt3l,xCubeh,xCubel,t1h,t1l);
711
+
712
+ Add22(&polyh,&polyl,t2h,t2l,tt3h,tt3l);
713
+
714
+ /* Reconstruction */
715
+
716
+ /* If we have not performed any range reduction, we have no reconstruction to do */
717
+ if (expoX >= 0) {
718
+ /* If we are here, we must perform reconstruction */
719
+
720
+ /* First reconstruction step */
721
+ Add12(r1h,r1t,2,polyh);
722
+ r1l = r1t + polyl;
723
+ Mul22(&rr1h,&rr1l,r1h,r1l,polyh,polyl);
724
+
725
+ if (expoX >= 1) {
726
+
727
+ /* Second reconstruction step */
728
+ Add12(r2h,r2t,2,rr1h);
729
+ r2l = r2t + rr1l;
730
+ Mul22(&rr2h,&rr2l,r2h,r2l,rr1h,rr1l);
731
+
732
+ if (expoX >= 2) {
733
+
734
+ /* Third reconstruction step */
735
+ Add12(r3h,r3t,2,rr2h);
736
+ r3l = r3t + rr2l;
737
+ Mul22(&rr3h,&rr3l,r3h,r3l,rr2h,rr2l);
738
+
739
+ /* expoX may be maximally 2 */
740
+
741
+ expm1h = rr3h;
742
+ expm1m = rr3l;
743
+
744
+ } else {
745
+ expm1h = rr2h;
746
+ expm1m = rr2l;
747
+ }
748
+
749
+ } else {
750
+ expm1h = rr1h;
751
+ expm1m = rr1l;
752
+ }
753
+
754
+ } else {
755
+ expm1h = polyh;
756
+ expm1m = polyl;
757
+ }
758
+
759
+ /* Rounding test */
760
+ TEST_AND_RETURN_RD(expm1h, expm1m, ROUNDCSTDIRECTRD);
761
+ {
762
+ expm1_direct_td(&expm1h, &expm1m, &expm1l, x, xSqHalfh, xSqHalfl, xSqh, xSql, expoX);
763
+
764
+ ReturnRoundDownwards3(expm1h, expm1m, expm1l);
765
+
766
+ } /* Accurate phase launched */
767
+
768
+ /* We cannot be here, since we return in all cases before */
769
+ }
770
+
771
+ /* If we are here, we can use expm1(x) = exp(x) - 1 */
772
+
773
+ /* Range reduction - exact part: compute k as double and as int */
774
+
775
+ xMultLog2InvMult2L = x * log2InvMult2L;
776
+ shiftedXMult = xMultLog2InvMult2L + shiftConst;
777
+ kd = shiftedXMult - shiftConst;
778
+ shiftedXMultdb.d = shiftedXMult;
779
+ k = shiftedXMultdb.i[LO];
780
+ M = k >> 12;
781
+ index1 = k & INDEXMASK1;
782
+ index2 = (k & INDEXMASK2) >> 6;
783
+
784
+ /* Range reduction - part affected by error - must be redone in accurate phase */
785
+ Mul12(&s1,&s2,msLog2Div2Lh,kd);
786
+ s3 = kd * msLog2Div2Lm;
787
+ s4 = s2 + s3;
788
+ s5 = x + s1;
789
+ Add12Cond(rh,rm,s5,s4);
790
+
791
+ /* Table reads - read only two double-doubles by now */
792
+ tbl1h = twoPowerIndex1[index1].hi;
793
+ tbl1m = twoPowerIndex1[index1].mi;
794
+ tbl2h = twoPowerIndex2[index2].hi;
795
+ tbl2m = twoPowerIndex2[index2].mi;
796
+
797
+ /* Quick phase starts here */
798
+
799
+ rhSquare = rh * rh;
800
+ rhC3 = quickCommonpolyC3h * rh;
801
+
802
+ rhSquareHalf = 0.5 * rhSquare;
803
+ monomialCube = rhC3 * rhSquare;
804
+ rhFour = rhSquare * rhSquare;
805
+
806
+ monomialFour = quickCommonpolyC4h * rhFour;
807
+
808
+ highPoly = monomialCube + monomialFour;
809
+
810
+ highPolyWithSquare = rhSquareHalf + highPoly;
811
+
812
+ /* Reconstruction: integration of table values */
813
+
814
+ Mul22(&tablesh,&tablesl,tbl1h,tbl1m,tbl2h,tbl2m);
815
+
816
+ t8 = rm + highPolyWithSquare;
817
+ t9 = rh + t8;
818
+
819
+ t10 = tablesh * t9;
820
+
821
+ Add12(t11,t12,tablesh,t10);
822
+ t13 = t12 + tablesl;
823
+ Add12(polyTblhdb.d,polyTblmdb.d,t11,t13);
824
+
825
+ /* Reconstruction: multiplication by 2^M */
826
+
827
+ /* Implement the multiplication by addition to overcome the
828
+ problem of the non-representability of 2^1024 (M = 1024)
829
+ This case is possible if polyTblhdb.d < 1
830
+ */
831
+
832
+ polyTblhdb.i[HI] += M << 20;
833
+ if(polyTblmdb.d!=0.0) /* predicted true, but it happens for x=-4.1588039009762204, thanks Morten */
834
+ polyTblmdb.i[HI] += M << 20;
835
+
836
+ exph = polyTblhdb.d;
837
+ expm = polyTblmdb.d;
838
+
839
+ /* Subtraction of 1
840
+
841
+ Testing if the operation is necessary is more expensive than
842
+ performing it in any case.
843
+
844
+ We may cancellate at most 2 bits in the subtraction for
845
+ arguments 1/4 <= x <= ln(2) (0.25 <= x <= 0.69)
846
+ We must therefore use conditional Add12s
847
+
848
+ Since we perform a subtraction, we may not have addition overflow towards +inf
849
+
850
+ */
851
+
852
+ Add12Cond(t1,t2,-1,exph);
853
+ t3 = t2 + expm;
854
+ Add12Cond(expm1h,expm1m,t1,t3);
855
+
856
+
857
+ /* Rounding test */
858
+ TEST_AND_RETURN_RD(expm1h, expm1m, ROUNDCSTCOMMONRD);
859
+ {
860
+ /* Rest of argument reduction for accurate phase */
861
+
862
+ Mul133(&msLog2Div2LMultKh,&msLog2Div2LMultKm,&msLog2Div2LMultKl,kd,msLog2Div2Lh,msLog2Div2Lm,msLog2Div2Ll);
863
+ t1 = x + msLog2Div2LMultKh;
864
+ Add12Cond(rh,t2,t1,msLog2Div2LMultKm);
865
+ Add12Cond(rm,rl,t2,msLog2Div2LMultKl);
866
+
867
+ /* Table reads for accurate phase */
868
+ tbl1l = twoPowerIndex1[index1].lo;
869
+ tbl2l = twoPowerIndex2[index2].lo;
870
+
871
+ /* Call accurate phase */
872
+ expm1_common_td(&expm1h, &expm1m, &expm1l, rh, rm, rl, tbl1h, tbl1m, tbl1l, tbl2h, tbl2m, tbl2l, M);
873
+
874
+ /* Final rounding */
875
+
876
+ ReturnRoundDownwards3(expm1h, expm1m, expm1l);
877
+ } /* Accurate phase launched */
878
+
879
+ /* We cannot be here since we return before in any case */
880
+ }
881
+
882
+ double expm1_ru(double x) {
883
+ db_number xdb, shiftedXMultdb, polyTblhdb, polyTblmdb;
884
+ int xIntHi, expoX, k, M, index1, index2;
885
+ double highPoly, tt1h, t1h, t1l, xSqh, xSql, xSqHalfh, xSqHalfl, xCubeh, xCubel, t2h, t2l, templ, tt3h, tt3l;
886
+ double polyh, polyl, expm1h, expm1m, expm1l;
887
+ double r1h, r1l, r1t, rr1h, rr1l;
888
+ double r2h, r2l, r2t, rr2h, rr2l;
889
+ double r3h, r3l, r3t, rr3h, rr3l;
890
+ double xMultLog2InvMult2L, shiftedXMult, kd, s1, s2, s3, s4, s5, rh, rm, rl;
891
+ double rhSquare, rhC3, rhSquareHalf, monomialCube, rhFour, monomialFour;
892
+ double tbl1h, tbl1m, tbl1l, tbl2h, tbl2m, tbl2l;
893
+ double highPolyWithSquare, tablesh, tablesl, t8, t9, t10, t11, t12, t13;
894
+ double exph, expm, t1, t2, t3;
895
+ double msLog2Div2LMultKh, msLog2Div2LMultKm, msLog2Div2LMultKl;
896
+ double middlePoly, doublePoly;
897
+
898
+ xdb.d = x;
899
+
900
+ /* Strip off the sign of x for the following tests */
901
+
902
+ xIntHi = xdb.i[HI] & 0x7fffffff;
903
+
904
+ /* Test if we are so small that we can return (a corrected) x as correct rounding */
905
+ if (xIntHi < RETURNXBOUND) {
906
+ /* The only algebraic result is 0 for x = +/-0; in this case, we return x = +/-0
907
+ The truncation rest x^2/2 + x^3/6 + ... is always positive
908
+ but less than 1 ulp in this case, so we round by adding 1 ulp
909
+ */
910
+
911
+ if (x == 0.0) return x;
912
+
913
+ if (xdb.i[HI] & 0x80000000) {
914
+ /* x is negative
915
+ We add 1 ulp by subtracting 1 in long
916
+ */
917
+ xdb.l--;
918
+ } else {
919
+ /* x is positive
920
+ We add 1 ulp by adding 1 in long
921
+ */
922
+ xdb.l++;
923
+ }
924
+ return xdb.d;
925
+ }
926
+
927
+
928
+ /* Filter out special cases like overflow, -1 in result, infinities and NaNs
929
+ The filters are not sharp, we have positive arguments that flow through
930
+ */
931
+ if (xIntHi >= SIMPLEOVERFLOWBOUND) {
932
+ /* Test if we are +/-inf or NaN */
933
+ if (xIntHi >= 0x7ff00000) {
934
+ /* Test if NaN */
935
+ if (((xIntHi & 0x000fffff) | xdb.i[LO]) != 0) {
936
+ /* NaN */
937
+ return x+x; /* return NaN */
938
+ }
939
+ /* Test if +inf or -inf */
940
+ if (xdb.i[HI] > 0) {
941
+ /* +inf */
942
+ return x+x; /* return +inf */
943
+ }
944
+
945
+ /* If we are here, we are -inf */
946
+ return -1.0;
947
+ }
948
+
949
+ /* If we are here, we are overflowed or a common case that flows through */
950
+
951
+ /* Test if we are actually overflowed */
952
+ if (x > OVERFLOWBOUND) {
953
+ return LARGEST * LARGEST; /* return +inf and set flag */
954
+ }
955
+ }
956
+
957
+ /* Test if we know already that we are -1.0 (+ correction depending on rounding mode) in result */
958
+ if (x < MINUSONEBOUND) {
959
+ /* Round up so we are -1.0 + 1ulp */
960
+ return MINUSONEPLUSONEULP;
961
+ }
962
+
963
+ /* Test if we have |x| <= 1/4-1/2ulp(1/4) for knowing if we use exp(x) or approximate directly */
964
+
965
+ if (xIntHi < DIRECTINTERVALBOUND) {
966
+ /* We approximate expm1 directly after a range reduction as follows
967
+
968
+ expm1(x) = (expm1(x/2) + 2) * expm1(x/2)
969
+
970
+ We perform the range reduction in such a way that finally |x| < 1/32
971
+ */
972
+
973
+ /* Extract the exponent of |x| and add 5 (2^5 = 32) */
974
+ expoX = ((xIntHi & 0x7ff00000) >> 20) - (1023 - 5);
975
+
976
+ /* If this particularily biased exponent expoX is negative, we are already less than 1/32 */
977
+ if (expoX >= 0) {
978
+ /* If we are here, we must perform range reduction */
979
+
980
+
981
+ /* We multiply x by 2^(-expoX-1) by bit manipulation
982
+ x cannot be denormalized so there is no danger
983
+ */
984
+ xdb.i[HI] += (-expoX-1) << 20;
985
+
986
+ /* We reassign the new x and maintain xIntHi */
987
+
988
+ xIntHi = xdb.i[HI] & 0x7fffffff;
989
+ x = xdb.d;
990
+ }
991
+
992
+ /* Here, we have always |x| < 1/32 */
993
+
994
+
995
+ /* Double precision evaluation steps and one double-double step */
996
+
997
+ Mul12(&xSqh,&xSql,x,x);
998
+
999
+ #if defined(PROCESSOR_HAS_FMA) && !defined(AVOID_FMA)
1000
+ middlePoly = FMA(quickDirectpolyC5h,x,quickDirectpolyC4h);
1001
+ #else
1002
+ middlePoly = quickDirectpolyC4h + x * quickDirectpolyC5h;
1003
+ #endif
1004
+
1005
+ doublePoly = middlePoly;
1006
+
1007
+ /* Special path: for small |x| we can truncate the polynomial */
1008
+
1009
+ if (xIntHi > SPECIALINTERVALBOUND) {
1010
+
1011
+ #if defined(PROCESSOR_HAS_FMA) && !defined(AVOID_FMA)
1012
+ highPoly = FMA(FMA(FMA(quickDirectpolyC9h ,x,quickDirectpolyC8h),x,
1013
+ quickDirectpolyC7h),x,quickDirectpolyC6h);
1014
+ #else
1015
+ highPoly = quickDirectpolyC6h + x * (quickDirectpolyC7h + x * (
1016
+ quickDirectpolyC8h + x * quickDirectpolyC9h));
1017
+ #endif
1018
+
1019
+ highPolyWithSquare = xSqh * highPoly;
1020
+
1021
+ doublePoly = middlePoly + highPolyWithSquare;
1022
+
1023
+ }
1024
+
1025
+ /* Double-double evaluation steps */
1026
+ tt1h = x * doublePoly;
1027
+
1028
+ xSqHalfh = 0.5 * xSqh;
1029
+ xSqHalfl = 0.5 * xSql;
1030
+ Add12(t2h,templ,x,xSqHalfh);
1031
+ t2l = templ + xSqHalfl;
1032
+
1033
+ Add12(t1h,t1l,quickDirectpolyC3h,tt1h);
1034
+ Mul122(&xCubeh,&xCubel,x,xSqh,xSql);
1035
+ Mul22(&tt3h,&tt3l,xCubeh,xCubel,t1h,t1l);
1036
+
1037
+ Add22(&polyh,&polyl,t2h,t2l,tt3h,tt3l);
1038
+
1039
+ /* Reconstruction */
1040
+
1041
+ /* If we have not performed any range reduction, we have no reconstruction to do */
1042
+ if (expoX >= 0) {
1043
+ /* If we are here, we must perform reconstruction */
1044
+
1045
+ /* First reconstruction step */
1046
+ Add12(r1h,r1t,2,polyh);
1047
+ r1l = r1t + polyl;
1048
+ Mul22(&rr1h,&rr1l,r1h,r1l,polyh,polyl);
1049
+
1050
+ if (expoX >= 1) {
1051
+
1052
+ /* Second reconstruction step */
1053
+ Add12(r2h,r2t,2,rr1h);
1054
+ r2l = r2t + rr1l;
1055
+ Mul22(&rr2h,&rr2l,r2h,r2l,rr1h,rr1l);
1056
+
1057
+ if (expoX >= 2) {
1058
+
1059
+ /* Third reconstruction step */
1060
+ Add12(r3h,r3t,2,rr2h);
1061
+ r3l = r3t + rr2l;
1062
+ Mul22(&rr3h,&rr3l,r3h,r3l,rr2h,rr2l);
1063
+
1064
+ /* expoX may be maximally 2 */
1065
+
1066
+ expm1h = rr3h;
1067
+ expm1m = rr3l;
1068
+
1069
+ } else {
1070
+ expm1h = rr2h;
1071
+ expm1m = rr2l;
1072
+ }
1073
+
1074
+ } else {
1075
+ expm1h = rr1h;
1076
+ expm1m = rr1l;
1077
+ }
1078
+
1079
+ } else {
1080
+ expm1h = polyh;
1081
+ expm1m = polyl;
1082
+ }
1083
+
1084
+ /* Rounding test */
1085
+ TEST_AND_RETURN_RU(expm1h, expm1m, ROUNDCSTDIRECTRD);
1086
+ {
1087
+ expm1_direct_td(&expm1h, &expm1m, &expm1l, x, xSqHalfh, xSqHalfl, xSqh, xSql, expoX);
1088
+
1089
+ ReturnRoundUpwards3(expm1h, expm1m, expm1l);
1090
+
1091
+ } /* Accurate phase launched */
1092
+
1093
+ /* We cannot be here, since we return in all cases before */
1094
+ }
1095
+
1096
+ /* If we are here, we can use expm1(x) = exp(x) - 1 */
1097
+
1098
+ /* Range reduction - exact part: compute k as double and as int */
1099
+
1100
+ xMultLog2InvMult2L = x * log2InvMult2L;
1101
+ shiftedXMult = xMultLog2InvMult2L + shiftConst;
1102
+ kd = shiftedXMult - shiftConst;
1103
+ shiftedXMultdb.d = shiftedXMult;
1104
+ k = shiftedXMultdb.i[LO];
1105
+ M = k >> 12;
1106
+ index1 = k & INDEXMASK1;
1107
+ index2 = (k & INDEXMASK2) >> 6;
1108
+
1109
+ /* Range reduction - part affected by error - must be redone in accurate phase */
1110
+ Mul12(&s1,&s2,msLog2Div2Lh,kd);
1111
+ s3 = kd * msLog2Div2Lm;
1112
+ s4 = s2 + s3;
1113
+ s5 = x + s1;
1114
+ Add12Cond(rh,rm,s5,s4);
1115
+
1116
+ /* Table reads - read only two double-doubles by now */
1117
+ tbl1h = twoPowerIndex1[index1].hi;
1118
+ tbl1m = twoPowerIndex1[index1].mi;
1119
+ tbl2h = twoPowerIndex2[index2].hi;
1120
+ tbl2m = twoPowerIndex2[index2].mi;
1121
+
1122
+ /* Quick phase starts here */
1123
+
1124
+ rhSquare = rh * rh;
1125
+ rhC3 = quickCommonpolyC3h * rh;
1126
+
1127
+ rhSquareHalf = 0.5 * rhSquare;
1128
+ monomialCube = rhC3 * rhSquare;
1129
+ rhFour = rhSquare * rhSquare;
1130
+
1131
+ monomialFour = quickCommonpolyC4h * rhFour;
1132
+
1133
+ highPoly = monomialCube + monomialFour;
1134
+
1135
+ highPolyWithSquare = rhSquareHalf + highPoly;
1136
+
1137
+ /* Reconstruction: integration of table values */
1138
+
1139
+ Mul22(&tablesh,&tablesl,tbl1h,tbl1m,tbl2h,tbl2m);
1140
+
1141
+ t8 = rm + highPolyWithSquare;
1142
+ t9 = rh + t8;
1143
+
1144
+ t10 = tablesh * t9;
1145
+
1146
+ Add12(t11,t12,tablesh,t10);
1147
+ t13 = t12 + tablesl;
1148
+ Add12(polyTblhdb.d,polyTblmdb.d,t11,t13);
1149
+
1150
+ /* Reconstruction: multiplication by 2^M */
1151
+
1152
+ /* Implement the multiplication by addition to overcome the
1153
+ problem of the non-representability of 2^1024 (M = 1024)
1154
+ This case is possible if polyTblhdb.d < 1
1155
+ */
1156
+
1157
+ polyTblhdb.i[HI] += M << 20;
1158
+ if(polyTblmdb.d!=0.0) /* predicted true, but it happens for x=-4.1588039009762204, thanks Morten */
1159
+ polyTblmdb.i[HI] += M << 20;
1160
+
1161
+ exph = polyTblhdb.d;
1162
+ expm = polyTblmdb.d;
1163
+
1164
+ /* Subtraction of 1
1165
+
1166
+ Testing if the operation is necessary is more expensive than
1167
+ performing it in any case.
1168
+
1169
+ We may cancellate at most 2 bits in the subtraction for
1170
+ arguments 1/4 <= x <= ln(2) (0.25 <= x <= 0.69)
1171
+ We must therefore use conditional Add12s
1172
+
1173
+ Since we perform a subtraction, we may not have addition overflow towards +inf
1174
+
1175
+ */
1176
+
1177
+ Add12Cond(t1,t2,-1,exph);
1178
+ t3 = t2 + expm;
1179
+ Add12Cond(expm1h,expm1m,t1,t3);
1180
+
1181
+
1182
+ /* Rounding test */
1183
+ TEST_AND_RETURN_RU(expm1h, expm1m, ROUNDCSTCOMMONRD);
1184
+ {
1185
+ /* Rest of argument reduction for accurate phase */
1186
+
1187
+ Mul133(&msLog2Div2LMultKh,&msLog2Div2LMultKm,&msLog2Div2LMultKl,kd,msLog2Div2Lh,msLog2Div2Lm,msLog2Div2Ll);
1188
+ t1 = x + msLog2Div2LMultKh;
1189
+ Add12Cond(rh,t2,t1,msLog2Div2LMultKm);
1190
+ Add12Cond(rm,rl,t2,msLog2Div2LMultKl);
1191
+
1192
+ /* Table reads for accurate phase */
1193
+ tbl1l = twoPowerIndex1[index1].lo;
1194
+ tbl2l = twoPowerIndex2[index2].lo;
1195
+
1196
+ /* Call accurate phase */
1197
+ expm1_common_td(&expm1h, &expm1m, &expm1l, rh, rm, rl, tbl1h, tbl1m, tbl1l, tbl2h, tbl2m, tbl2l, M);
1198
+
1199
+ /* Final rounding */
1200
+
1201
+ ReturnRoundUpwards3(expm1h, expm1m, expm1l);
1202
+ } /* Accurate phase launched */
1203
+
1204
+ /* We cannot be here since we return before in any case */
1205
+ }
1206
+
1207
+ double expm1_rz(double x) {
1208
+ db_number xdb, shiftedXMultdb, polyTblhdb, polyTblmdb;
1209
+ int xIntHi, expoX, k, M, index1, index2;
1210
+ double highPoly, tt1h, t1h, t1l, xSqh, xSql, xSqHalfh, xSqHalfl, xCubeh, xCubel, t2h, t2l, templ, tt3h, tt3l;
1211
+ double polyh, polyl, expm1h, expm1m, expm1l;
1212
+ double r1h, r1l, r1t, rr1h, rr1l;
1213
+ double r2h, r2l, r2t, rr2h, rr2l;
1214
+ double r3h, r3l, r3t, rr3h, rr3l;
1215
+ double xMultLog2InvMult2L, shiftedXMult, kd, s1, s2, s3, s4, s5, rh, rm, rl;
1216
+ double rhSquare, rhC3, rhSquareHalf, monomialCube, rhFour, monomialFour;
1217
+ double tbl1h, tbl1m, tbl1l, tbl2h, tbl2m, tbl2l;
1218
+ double highPolyWithSquare, tablesh, tablesl, t8, t9, t10, t11, t12, t13;
1219
+ double exph, expm, t1, t2, t3;
1220
+ double msLog2Div2LMultKh, msLog2Div2LMultKm, msLog2Div2LMultKl;
1221
+ double middlePoly, doublePoly;
1222
+
1223
+ xdb.d = x;
1224
+
1225
+ /* Strip off the sign of x for the following tests */
1226
+
1227
+ xIntHi = xdb.i[HI] & 0x7fffffff;
1228
+
1229
+ /* Test if we are so small that we can return (a corrected) x as correct rounding */
1230
+ if (xIntHi < RETURNXBOUND) {
1231
+ /* The only algebraic result is 0 for x = +/- 0; in this case, we can return x = +/- 0
1232
+ expm1 is positive for positive x, negative for negative x
1233
+ The truncation rest x^2/2 + x^3/6 + ... is always positive
1234
+ but less than 1 ulp in this case, so we round as follows:
1235
+
1236
+ - x is positive => expm1 is positive => round downwards => truncate by returning x
1237
+ - x is negative => expm1 is negative => round upwards => add 1 ulp
1238
+ */
1239
+
1240
+ if (x == 0.0) return x;
1241
+
1242
+ if (xdb.i[HI] & 0x80000000) {
1243
+ /* x is negative
1244
+ We add 1 ulp by subtracting 1 in long
1245
+ */
1246
+ xdb.l--;
1247
+ return xdb.d;
1248
+ } else {
1249
+ /* x is positive
1250
+ We do nothing (see above)
1251
+ */
1252
+ return x;
1253
+ }
1254
+ }
1255
+
1256
+
1257
+ /* Filter out special cases like overflow, -1 in result, infinities and NaNs
1258
+ The filters are not sharp, we have positive arguments that flow through
1259
+ */
1260
+ if (xIntHi >= SIMPLEOVERFLOWBOUND) {
1261
+ /* Test if we are +/-inf or NaN */
1262
+ if (xIntHi >= 0x7ff00000) {
1263
+ /* Test if NaN */
1264
+ if (((xIntHi & 0x000fffff) | xdb.i[LO]) != 0) {
1265
+ /* NaN */
1266
+ return x+x; /* return NaN */
1267
+ }
1268
+ /* Test if +inf or -inf */
1269
+ if (xdb.i[HI] > 0) {
1270
+ /* +inf */
1271
+ return x+x; /* return +inf */
1272
+ }
1273
+
1274
+ /* If we are here, we are -inf */
1275
+ return -1.0;
1276
+ }
1277
+
1278
+ /* If we are here, we are overflowed or a common case that flows through */
1279
+
1280
+ /* Test if we are actually overflowed */
1281
+ if (x > OVERFLOWBOUND) {
1282
+ /* We would be overflowed but as we are rounding towards zero, i.e. downwards,
1283
+ the nearest number lesser than the exact result is the greatest
1284
+ normal. In any case, we must raise the inexact flag.
1285
+ */
1286
+ return LARGEST * (1.0 + SMALLEST);
1287
+ }
1288
+ }
1289
+
1290
+ /* Test if we know already that we are -1.0 (+ correction depending on rounding mode) in result */
1291
+ if (x < MINUSONEBOUND) {
1292
+ /* We round towards zero, i.e. upwards, so we return -1.0+1ulp */
1293
+ return MINUSONEPLUSONEULP;
1294
+ }
1295
+
1296
+ /* Test if we have |x| <= 1/4-1/2ulp(1/4) for knowing if we use exp(x) or approximate directly */
1297
+
1298
+ if (xIntHi < DIRECTINTERVALBOUND) {
1299
+
1300
+ /* We approximate expm1 directly after a range reduction as follows
1301
+
1302
+ expm1(x) = (expm1(x/2) + 2) * expm1(x/2)
1303
+
1304
+ We perform the range reduction in such a way that finally |x| < 1/32
1305
+ */
1306
+
1307
+ /* Extract the exponent of |x| and add 5 (2^5 = 32) */
1308
+ expoX = ((xIntHi & 0x7ff00000) >> 20) - (1023 - 5);
1309
+
1310
+ /* If this particularily biased exponent expoX is negative, we are already less than 1/32 */
1311
+ if (expoX >= 0) {
1312
+ /* If we are here, we must perform range reduction */
1313
+
1314
+
1315
+ /* We multiply x by 2^(-expoX-1) by bit manipulation
1316
+ x cannot be denormalized so there is no danger
1317
+ */
1318
+ xdb.i[HI] += (-expoX-1) << 20;
1319
+
1320
+ /* We reassign the new x and maintain xIntHi */
1321
+
1322
+ xIntHi = xdb.i[HI] & 0x7fffffff;
1323
+ x = xdb.d;
1324
+ }
1325
+ /* Here, we have always |x| < 1/32 */
1326
+
1327
+
1328
+ /* Double precision evaluation steps and one double-double step */
1329
+
1330
+ Mul12(&xSqh,&xSql,x,x);
1331
+
1332
+ #if defined(PROCESSOR_HAS_FMA) && !defined(AVOID_FMA)
1333
+ middlePoly = FMA(quickDirectpolyC5h,x,quickDirectpolyC4h);
1334
+ #else
1335
+ middlePoly = quickDirectpolyC4h + x * quickDirectpolyC5h;
1336
+ #endif
1337
+
1338
+ doublePoly = middlePoly;
1339
+
1340
+ /* Special path: for small |x| we can truncate the polynomial */
1341
+
1342
+ if (xIntHi > SPECIALINTERVALBOUND) {
1343
+
1344
+ #if defined(PROCESSOR_HAS_FMA) && !defined(AVOID_FMA)
1345
+ highPoly = FMA(FMA(FMA(quickDirectpolyC9h ,x,quickDirectpolyC8h),x,
1346
+ quickDirectpolyC7h),x,quickDirectpolyC6h);
1347
+ #else
1348
+ highPoly = quickDirectpolyC6h + x * (quickDirectpolyC7h + x * (
1349
+ quickDirectpolyC8h + x * quickDirectpolyC9h));
1350
+ #endif
1351
+
1352
+ highPolyWithSquare = xSqh * highPoly;
1353
+
1354
+ doublePoly = middlePoly + highPolyWithSquare;
1355
+
1356
+ }
1357
+
1358
+ /* Double-double evaluation steps */
1359
+ tt1h = x * doublePoly;
1360
+
1361
+ xSqHalfh = 0.5 * xSqh;
1362
+ xSqHalfl = 0.5 * xSql;
1363
+ Add12(t2h,templ,x,xSqHalfh);
1364
+ t2l = templ + xSqHalfl;
1365
+
1366
+ Add12(t1h,t1l,quickDirectpolyC3h,tt1h);
1367
+ Mul122(&xCubeh,&xCubel,x,xSqh,xSql);
1368
+ Mul22(&tt3h,&tt3l,xCubeh,xCubel,t1h,t1l);
1369
+
1370
+ Add22(&polyh,&polyl,t2h,t2l,tt3h,tt3l);
1371
+
1372
+ /* Reconstruction */
1373
+
1374
+ /* If we have not performed any range reduction, we have no reconstruction to do */
1375
+ if (expoX >= 0) {
1376
+ /* If we are here, we must perform reconstruction */
1377
+
1378
+ /* First reconstruction step */
1379
+ Add12(r1h,r1t,2,polyh);
1380
+ r1l = r1t + polyl;
1381
+ Mul22(&rr1h,&rr1l,r1h,r1l,polyh,polyl);
1382
+
1383
+ if (expoX >= 1) {
1384
+
1385
+ /* Second reconstruction step */
1386
+ Add12(r2h,r2t,2,rr1h);
1387
+ r2l = r2t + rr1l;
1388
+ Mul22(&rr2h,&rr2l,r2h,r2l,rr1h,rr1l);
1389
+
1390
+ if (expoX >= 2) {
1391
+
1392
+ /* Third reconstruction step */
1393
+ Add12(r3h,r3t,2,rr2h);
1394
+ r3l = r3t + rr2l;
1395
+ Mul22(&rr3h,&rr3l,r3h,r3l,rr2h,rr2l);
1396
+
1397
+ /* expoX may be maximally 2 */
1398
+
1399
+ expm1h = rr3h;
1400
+ expm1m = rr3l;
1401
+
1402
+ } else {
1403
+ expm1h = rr2h;
1404
+ expm1m = rr2l;
1405
+ }
1406
+
1407
+ } else {
1408
+ expm1h = rr1h;
1409
+ expm1m = rr1l;
1410
+ }
1411
+
1412
+ } else {
1413
+ expm1h = polyh;
1414
+ expm1m = polyl;
1415
+ }
1416
+
1417
+ /* Rounding test */
1418
+ TEST_AND_RETURN_RZ(expm1h, expm1m, ROUNDCSTDIRECTRD);
1419
+ {
1420
+ expm1_direct_td(&expm1h, &expm1m, &expm1l, x, xSqHalfh, xSqHalfl, xSqh, xSql, expoX);
1421
+
1422
+ ReturnRoundTowardsZero3(expm1h, expm1m, expm1l);
1423
+
1424
+ } /* Accurate phase launched */
1425
+
1426
+ /* We cannot be here, since we return in all cases before */
1427
+ }
1428
+
1429
+ /* If we are here, we can use expm1(x) = exp(x) - 1 */
1430
+
1431
+ /* Range reduction - exact part: compute k as double and as int */
1432
+
1433
+ xMultLog2InvMult2L = x * log2InvMult2L;
1434
+ shiftedXMult = xMultLog2InvMult2L + shiftConst;
1435
+ kd = shiftedXMult - shiftConst;
1436
+ shiftedXMultdb.d = shiftedXMult;
1437
+ k = shiftedXMultdb.i[LO];
1438
+ M = k >> 12;
1439
+ index1 = k & INDEXMASK1;
1440
+ index2 = (k & INDEXMASK2) >> 6;
1441
+
1442
+ /* Range reduction - part affected by error - must be redone in accurate phase */
1443
+ Mul12(&s1,&s2,msLog2Div2Lh,kd);
1444
+ s3 = kd * msLog2Div2Lm;
1445
+ s4 = s2 + s3;
1446
+ s5 = x + s1;
1447
+ Add12Cond(rh,rm,s5,s4);
1448
+
1449
+ /* Table reads - read only two double-doubles by now */
1450
+ tbl1h = twoPowerIndex1[index1].hi;
1451
+ tbl1m = twoPowerIndex1[index1].mi;
1452
+ tbl2h = twoPowerIndex2[index2].hi;
1453
+ tbl2m = twoPowerIndex2[index2].mi;
1454
+
1455
+ /* Quick phase starts here */
1456
+
1457
+ rhSquare = rh * rh;
1458
+ rhC3 = quickCommonpolyC3h * rh;
1459
+
1460
+ rhSquareHalf = 0.5 * rhSquare;
1461
+ monomialCube = rhC3 * rhSquare;
1462
+ rhFour = rhSquare * rhSquare;
1463
+
1464
+ monomialFour = quickCommonpolyC4h * rhFour;
1465
+
1466
+ highPoly = monomialCube + monomialFour;
1467
+
1468
+ highPolyWithSquare = rhSquareHalf + highPoly;
1469
+
1470
+ /* Reconstruction: integration of table values */
1471
+
1472
+ Mul22(&tablesh,&tablesl,tbl1h,tbl1m,tbl2h,tbl2m);
1473
+
1474
+ t8 = rm + highPolyWithSquare;
1475
+ t9 = rh + t8;
1476
+
1477
+ t10 = tablesh * t9;
1478
+
1479
+ Add12(t11,t12,tablesh,t10);
1480
+ t13 = t12 + tablesl;
1481
+ Add12(polyTblhdb.d,polyTblmdb.d,t11,t13);
1482
+
1483
+ /* Reconstruction: multiplication by 2^M */
1484
+
1485
+ /* Implement the multiplication by addition to overcome the
1486
+ problem of the non-representability of 2^1024 (M = 1024)
1487
+ This case is possible if polyTblhdb.d < 1
1488
+ */
1489
+
1490
+ polyTblhdb.i[HI] += M << 20;
1491
+ if(polyTblmdb.d!=0.0) /* predicted true, but it happens for x=-4.1588039009762204, thanks Morten */
1492
+ polyTblmdb.i[HI] += M << 20;
1493
+
1494
+ exph = polyTblhdb.d;
1495
+ expm = polyTblmdb.d;
1496
+
1497
+ /* Subtraction of 1
1498
+
1499
+ Testing if the operation is necessary is more expensive than
1500
+ performing it in any case.
1501
+
1502
+ We may cancellate at most 2 bits in the subtraction for
1503
+ arguments 1/4 <= x <= ln(2) (0.25 <= x <= 0.69)
1504
+ We must therefore use conditional Add12s
1505
+
1506
+ Since we perform a subtraction, we may not have addition overflow towards +inf
1507
+
1508
+ */
1509
+
1510
+ Add12Cond(t1,t2,-1,exph);
1511
+ t3 = t2 + expm;
1512
+ Add12Cond(expm1h,expm1m,t1,t3);
1513
+
1514
+
1515
+ /* Rounding test */
1516
+ TEST_AND_RETURN_RZ(expm1h, expm1m, ROUNDCSTCOMMONRD);
1517
+ {
1518
+
1519
+ /* Rest of argument reduction for accurate phase */
1520
+
1521
+ Mul133(&msLog2Div2LMultKh,&msLog2Div2LMultKm,&msLog2Div2LMultKl,kd,msLog2Div2Lh,msLog2Div2Lm,msLog2Div2Ll);
1522
+ t1 = x + msLog2Div2LMultKh;
1523
+ Add12Cond(rh,t2,t1,msLog2Div2LMultKm);
1524
+ Add12Cond(rm,rl,t2,msLog2Div2LMultKl);
1525
+
1526
+ /* Table reads for accurate phase */
1527
+ tbl1l = twoPowerIndex1[index1].lo;
1528
+ tbl2l = twoPowerIndex2[index2].lo;
1529
+
1530
+ /* Call accurate phase */
1531
+ expm1_common_td(&expm1h, &expm1m, &expm1l, rh, rm, rl, tbl1h, tbl1m, tbl1l, tbl2h, tbl2m, tbl2l, M);
1532
+
1533
+ /* Final rounding */
1534
+
1535
+ ReturnRoundTowardsZero3(expm1h, expm1m, expm1l);
1536
+ } /* Accurate phase launched */
1537
+
1538
+ /* We cannot be here since we return before in any case */
1539
+ }
1540
+
1541
+ #ifdef BUILD_INTERVAL_FUNCTIONS
1542
+ interval j_expm1(interval x)
1543
+ {
1544
+ interval res;
1545
+ db_number xdb_inf, shiftedXMultdb_inf, polyTblhdb_inf, polyTblmdb_inf;
1546
+ int xIntHi_inf, expoX_inf, k_inf, M_inf, index1_inf, index2_inf;
1547
+ double x_inf, x_sup;
1548
+ double res_inf,res_sup;
1549
+ double restemp_inf, restemp_sup;
1550
+ double highPoly_inf, tt1h_inf, t1h_inf, t1l_inf, xSqh_inf, xSql_inf, xSqHalfh_inf, xSqHalfl_inf, xCubeh_inf, xCubel_inf, t2h_inf, t2l_inf, templ_inf, tt3h_inf, tt3l_inf;
1551
+ double polyh_inf, polyl_inf, expm1h_inf, expm1m_inf, expm1l_inf;
1552
+ double r1h_inf, r1l_inf, r1t_inf, rr1h_inf, rr1l_inf;
1553
+ double r2h_inf, r2l_inf, r2t_inf, rr2h_inf, rr2l_inf;
1554
+ double r3h_inf, r3l_inf, r3t_inf, rr3h_inf, rr3l_inf;
1555
+ double xMultLog2InvMult2L_inf, shiftedXMult_inf, kd_inf, s1_inf, s2_inf, s3_inf, s4_inf, s5_inf, rh_inf, rm_inf, rl_inf;
1556
+ double rhSquare_inf, rhC3_inf, rhSquareHalf_inf, monomialCube_inf, rhFour_inf, monomialFour_inf;
1557
+ double tbl1h_inf, tbl1m_inf, tbl1l_inf, tbl2h_inf, tbl2m_inf, tbl2l_inf;
1558
+ double highPolyWithSquare_inf, tablesh_inf, tablesl_inf, t8_inf, t9_inf, t10_inf, t11_inf, t12_inf, t13_inf;
1559
+ double exph_inf, expm_inf, t1_inf, t2_inf, t3_inf;
1560
+ double msLog2Div2LMultKh_inf, msLog2Div2LMultKm_inf, msLog2Div2LMultKl_inf;
1561
+ double middlePoly_inf, doublePoly_inf;
1562
+ int roundable;
1563
+ int infDone, supDone;
1564
+ infDone=0; supDone=0;
1565
+
1566
+ db_number xdb_sup, shiftedXMultdb_sup, polyTblhdb_sup, polyTblmdb_sup;
1567
+ int xIntHi_sup, expoX_sup, k_sup, M_sup, index1_sup, index2_sup;
1568
+ double highPoly_sup, tt1h_sup, t1h_sup, t1l_sup, xSqh_sup, xSql_sup, xSqHalfh_sup, xSqHalfl_sup, xCubeh_sup, xCubel_sup, t2h_sup, t2l_sup, templ_sup, tt3h_sup, tt3l_sup;
1569
+ double polyh_sup, polyl_sup, expm1h_sup, expm1m_sup, expm1l_sup;
1570
+ double r1h_sup, r1l_sup, r1t_sup, rr1h_sup, rr1l_sup;
1571
+ double r2h_sup, r2l_sup, r2t_sup, rr2h_sup, rr2l_sup;
1572
+ double r3h_sup, r3l_sup, r3t_sup, rr3h_sup, rr3l_sup;
1573
+ double xMultLog2InvMult2L_sup, shiftedXMult_sup, kd_sup, s1_sup, s2_sup, s3_sup, s4_sup, s5_sup, rh_sup, rm_sup, rl_sup;
1574
+ double rhSquare_sup, rhC3_sup, rhSquareHalf_sup, monomialCube_sup, rhFour_sup, monomialFour_sup;
1575
+ double tbl1h_sup, tbl1m_sup, tbl1l_sup, tbl2h_sup, tbl2m_sup, tbl2l_sup;
1576
+ double highPolyWithSquare_sup, tablesh_sup, tablesl_sup, t8_sup, t9_sup, t10_sup, t11_sup, t12_sup, t13_sup;
1577
+ double exph_sup, expm_sup, t1_sup, t2_sup, t3_sup;
1578
+ double msLog2Div2LMultKh_sup, msLog2Div2LMultKm_sup, msLog2Div2LMultKl_sup;
1579
+ double middlePoly_sup, doublePoly_sup;
1580
+
1581
+ x_inf=LOW(x);
1582
+ x_sup=UP(x);
1583
+
1584
+ xdb_inf.d = x_inf;
1585
+ xdb_sup.d = x_sup;
1586
+
1587
+
1588
+ /* Strip off the sign of x for the following tests */
1589
+
1590
+ xIntHi_inf = xdb_inf.i[HI] & 0x7fffffff;
1591
+ xIntHi_sup = xdb_sup.i[HI] & 0x7fffffff;
1592
+
1593
+ /* Test if we are so small that we can return (a corrected) x as correct rounding */
1594
+
1595
+ if ( __builtin_expect(
1596
+ (xIntHi_inf < RETURNXBOUND) ||
1597
+ ((xIntHi_inf >= SIMPLEOVERFLOWBOUND) && (xIntHi_inf >= 0x7ff00000)) ||
1598
+ ((xIntHi_inf >= SIMPLEOVERFLOWBOUND) && (xIntHi_inf >= 0x7ff00000) && (((xIntHi_inf & 0x000fffff) | xdb_inf.i[LO]) != 0)) ||
1599
+ ((xIntHi_inf >= SIMPLEOVERFLOWBOUND) && (xIntHi_inf >= 0x7ff00000) && (xdb_inf.i[HI] > 0)) ||
1600
+ ((xIntHi_inf >= SIMPLEOVERFLOWBOUND) && (x_inf > OVERFLOWBOUND)) ||
1601
+ (x_inf < MINUSONEBOUND) ||
1602
+ (xIntHi_sup < RETURNXBOUND) ||
1603
+ ((xIntHi_sup < RETURNXBOUND) && (x_sup == 0.0)) ||
1604
+ ((xIntHi_sup >= SIMPLEOVERFLOWBOUND) && (xIntHi_sup >= 0x7ff00000)) ||
1605
+ ((xIntHi_sup >= SIMPLEOVERFLOWBOUND) && (xIntHi_sup >= 0x7ff00000) && (((xIntHi_sup & 0x000fffff) | xdb_sup.i[LO]) != 0)) ||
1606
+ ((xIntHi_sup >= SIMPLEOVERFLOWBOUND) && (xIntHi_sup >= 0x7ff00000) && (xdb_sup.i[HI] > 0)) ||
1607
+ ((xIntHi_sup >= SIMPLEOVERFLOWBOUND) && (x_sup > OVERFLOWBOUND)) ||
1608
+ (x_sup < MINUSONEBOUND)
1609
+ ,FALSE))
1610
+ {
1611
+ ASSIGN_LOW(res,expm1_rd(LOW(x)));
1612
+ ASSIGN_UP(res,expm1_ru(UP(x)));
1613
+ return res;
1614
+ }
1615
+
1616
+ if (__builtin_expect((xIntHi_inf < DIRECTINTERVALBOUND) && (xIntHi_sup < DIRECTINTERVALBOUND),TRUE)) {
1617
+ /* We approximate expm1 directly after a range reduction as follows
1618
+
1619
+ expm1(x) = (expm1(x/2) + 2) * expm1(x/2)
1620
+
1621
+ We perform the range reduction in such a way that finally |x| < 1/32
1622
+ */
1623
+
1624
+ /* Extract the exponent of |x| and add 5 (2^5 = 32) */
1625
+ expoX_inf = ((xIntHi_inf & 0x7ff00000) >> 20) - (1023 - 5);
1626
+ expoX_sup = ((xIntHi_sup & 0x7ff00000) >> 20) - (1023 - 5);
1627
+
1628
+ /* If this particularily biased exponent expoX is negative, we are already less than 1/32 */
1629
+ if (expoX_inf >= 0) {
1630
+ /* If we are here, we must perform range reduction */
1631
+
1632
+
1633
+ /* We multiply x by 2^(-expoX-1) by bit manipulation
1634
+ x cannot be denormalized so there is no danger
1635
+ */
1636
+ xdb_inf.i[HI] += (-expoX_inf-1) << 20;
1637
+
1638
+ /* We reassign the new x and maintain xIntHi */
1639
+
1640
+ xIntHi_inf = xdb_inf.i[HI] & 0x7fffffff;
1641
+ x_inf = xdb_inf.d;
1642
+ }
1643
+
1644
+ if (expoX_sup >= 0) {
1645
+ /* If we are here, we must perform range reduction */
1646
+
1647
+
1648
+ /* We multiply x by 2^(-expoX-1) by bit manipulation
1649
+ x cannot be denormalized so there is no danger
1650
+ */
1651
+ xdb_sup.i[HI] += (-expoX_sup-1) << 20;
1652
+
1653
+ /* We reassign the new x and maintain xIntHi */
1654
+
1655
+ xIntHi_sup = xdb_sup.i[HI] & 0x7fffffff;
1656
+ x_sup = xdb_sup.d;
1657
+ }
1658
+
1659
+ /* Here, we have always |x| < 1/32 */
1660
+
1661
+
1662
+ /* Double precision evaluation steps and one double-double step */
1663
+
1664
+ Mul12(&xSqh_inf,&xSql_inf,x_inf,x_inf);
1665
+ Mul12(&xSqh_sup,&xSql_sup,x_sup,x_sup);
1666
+
1667
+ #if defined(PROCESSOR_HAS_FMA) && !defined(AVOID_FMA)
1668
+ middlePoly_inf = FMA(quickDirectpolyC5h,x_inf,quickDirectpolyC4h);
1669
+ middlePoly_sup = FMA(quickDirectpolyC5h,x_sup,quickDirectpolyC4h);
1670
+ #else
1671
+ middlePoly_inf = quickDirectpolyC4h + x_inf * quickDirectpolyC5h;
1672
+ middlePoly_sup = quickDirectpolyC4h + x_sup * quickDirectpolyC5h;
1673
+ #endif
1674
+
1675
+ doublePoly_inf = middlePoly_inf;
1676
+ doublePoly_sup = middlePoly_sup;
1677
+
1678
+ /* Special path: for small |x| we can truncate the polynomial */
1679
+
1680
+ if (xIntHi_inf > SPECIALINTERVALBOUND) {
1681
+
1682
+ #if defined(PROCESSOR_HAS_FMA) && !defined(AVOID_FMA)
1683
+ highPoly_inf = FMA(FMA(FMA(quickDirectpolyC9h ,x_inf,quickDirectpolyC8h),x_inf,
1684
+ quickDirectpolyC7h),x_inf,quickDirectpolyC6h);
1685
+ #else
1686
+ highPoly_inf = quickDirectpolyC6h + x_inf * (quickDirectpolyC7h + x_inf * (
1687
+ quickDirectpolyC8h + x_inf * quickDirectpolyC9h));
1688
+ #endif
1689
+
1690
+ highPolyWithSquare_inf = xSqh_inf * highPoly_inf;
1691
+
1692
+ doublePoly_inf = middlePoly_inf + highPolyWithSquare_inf;
1693
+
1694
+ }
1695
+ if (xIntHi_sup > SPECIALINTERVALBOUND) {
1696
+
1697
+ #if defined(PROCESSOR_HAS_FMA) && !defined(AVOID_FMA)
1698
+ highPoly_sup = FMA(FMA(FMA(quickDirectpolyC9h ,x_sup,quickDirectpolyC8h),x_sup,
1699
+ quickDirectpolyC7h),x_sup,quickDirectpolyC6h);
1700
+ #else
1701
+ highPoly_sup = quickDirectpolyC6h + x_sup * (quickDirectpolyC7h + x_sup * (
1702
+ quickDirectpolyC8h + x_sup * quickDirectpolyC9h));
1703
+ #endif
1704
+
1705
+ highPolyWithSquare_sup = xSqh_sup * highPoly_sup;
1706
+
1707
+ doublePoly_sup = middlePoly_sup + highPolyWithSquare_sup;
1708
+
1709
+ }
1710
+
1711
+ /* Double-double evaluation steps */
1712
+ tt1h_inf = x_inf * doublePoly_inf;
1713
+ tt1h_sup = x_sup * doublePoly_sup;
1714
+
1715
+ xSqHalfh_inf = 0.5 * xSqh_inf;
1716
+ xSqHalfh_sup = 0.5 * xSqh_sup;
1717
+ xSqHalfl_inf = 0.5 * xSql_inf;
1718
+ xSqHalfl_sup = 0.5 * xSql_sup;
1719
+ Add12(t2h_inf,templ_inf,x_inf,xSqHalfh_inf);
1720
+ Add12(t2h_sup,templ_sup,x_sup,xSqHalfh_sup);
1721
+ t2l_inf = templ_inf + xSqHalfl_inf;
1722
+ t2l_sup = templ_sup + xSqHalfl_sup;
1723
+
1724
+ Add12(t1h_inf,t1l_inf,quickDirectpolyC3h,tt1h_inf);
1725
+ Add12(t1h_sup,t1l_sup,quickDirectpolyC3h,tt1h_sup);
1726
+ Mul122(&xCubeh_inf,&xCubel_inf,x_inf,xSqh_inf,xSql_inf);
1727
+ Mul122(&xCubeh_sup,&xCubel_sup,x_sup,xSqh_sup,xSql_sup);
1728
+ Mul22(&tt3h_inf,&tt3l_inf,xCubeh_inf,xCubel_inf,t1h_inf,t1l_inf);
1729
+ Mul22(&tt3h_sup,&tt3l_sup,xCubeh_sup,xCubel_sup,t1h_sup,t1l_sup);
1730
+
1731
+ Add22(&polyh_inf,&polyl_inf,t2h_inf,t2l_inf,tt3h_inf,tt3l_inf);
1732
+ Add22(&polyh_sup,&polyl_sup,t2h_sup,t2l_sup,tt3h_sup,tt3l_sup);
1733
+
1734
+ /* Reconstruction */
1735
+
1736
+ /* If we have not performed any range reduction, we have no reconstruction to do */
1737
+ if (expoX_inf >= 0) {
1738
+ /* If we are here, we must perform reconstruction */
1739
+
1740
+ /* First reconstruction step */
1741
+ Add12(r1h_inf,r1t_inf,2,polyh_inf);
1742
+ r1l_inf = r1t_inf + polyl_inf;
1743
+ Mul22(&rr1h_inf,&rr1l_inf,r1h_inf,r1l_inf,polyh_inf,polyl_inf);
1744
+
1745
+ if (expoX_inf >= 1) {
1746
+
1747
+ /* Second reconstruction step */
1748
+ Add12(r2h_inf,r2t_inf,2,rr1h_inf);
1749
+ r2l_inf = r2t_inf + rr1l_inf;
1750
+ Mul22(&rr2h_inf,&rr2l_inf,r2h_inf,r2l_inf,rr1h_inf,rr1l_inf);
1751
+
1752
+ if (expoX_inf >= 2) {
1753
+
1754
+ /* Third reconstruction step */
1755
+ Add12(r3h_inf,r3t_inf,2,rr2h_inf);
1756
+ r3l_inf = r3t_inf + rr2l_inf;
1757
+ Mul22(&rr3h_inf,&rr3l_inf,r3h_inf,r3l_inf,rr2h_inf,rr2l_inf);
1758
+
1759
+ /* expoX may be maximally 2 */
1760
+
1761
+ expm1h_inf = rr3h_inf;
1762
+ expm1m_inf = rr3l_inf;
1763
+
1764
+ } else {
1765
+ expm1h_inf = rr2h_inf;
1766
+ expm1m_inf = rr2l_inf;
1767
+ }
1768
+
1769
+ } else {
1770
+ expm1h_inf = rr1h_inf;
1771
+ expm1m_inf = rr1l_inf;
1772
+ }
1773
+
1774
+ } else {
1775
+ expm1h_inf = polyh_inf;
1776
+ expm1m_inf = polyl_inf;
1777
+ }
1778
+ if (expoX_sup >= 0) {
1779
+ /* If we are here, we must perform reconstruction */
1780
+
1781
+ /* First reconstruction step */
1782
+ Add12(r1h_sup,r1t_sup,2,polyh_sup);
1783
+ r1l_sup = r1t_sup + polyl_sup;
1784
+ Mul22(&rr1h_sup,&rr1l_sup,r1h_sup,r1l_sup,polyh_sup,polyl_sup);
1785
+
1786
+ if (expoX_sup >= 1) {
1787
+
1788
+ /* Second reconstruction step */
1789
+ Add12(r2h_sup,r2t_sup,2,rr1h_sup);
1790
+ r2l_sup = r2t_sup + rr1l_sup;
1791
+ Mul22(&rr2h_sup,&rr2l_sup,r2h_sup,r2l_sup,rr1h_sup,rr1l_sup);
1792
+
1793
+ if (expoX_sup >= 2) {
1794
+
1795
+ /* Third reconstruction step */
1796
+ Add12(r3h_sup,r3t_sup,2,rr2h_sup);
1797
+ r3l_sup = r3t_sup + rr2l_sup;
1798
+ Mul22(&rr3h_sup,&rr3l_sup,r3h_sup,r3l_sup,rr2h_sup,rr2l_sup);
1799
+
1800
+ /* expoX may be maximally 2 */
1801
+
1802
+ expm1h_sup = rr3h_sup;
1803
+ expm1m_sup = rr3l_sup;
1804
+
1805
+ } else {
1806
+ expm1h_sup = rr2h_sup;
1807
+ expm1m_sup = rr2l_sup;
1808
+ }
1809
+
1810
+ } else {
1811
+ expm1h_sup = rr1h_sup;
1812
+ expm1m_sup = rr1l_sup;
1813
+ }
1814
+
1815
+ } else {
1816
+ expm1h_sup = polyh_sup;
1817
+ expm1m_sup = polyl_sup;
1818
+ }
1819
+
1820
+
1821
+ /* Rounding test */
1822
+ TEST_AND_COPY_RDRU_EXPM1(roundable,restemp_inf,expm1h_inf, expm1m_inf, restemp_sup,expm1h_sup, expm1m_sup, ROUNDCSTDIRECTRD);
1823
+ if((roundable==2) || (roundable==0))
1824
+ {
1825
+ expm1_direct_td(&expm1h_inf, &expm1m_inf, &expm1l_inf, x_inf, xSqHalfh_inf, xSqHalfl_inf, xSqh_inf, xSql_inf, expoX_inf);
1826
+
1827
+ RoundDownwards3(&restemp_inf,expm1h_inf, expm1m_inf, expm1l_inf);
1828
+
1829
+ } /* Accurate phase launched */
1830
+ if((roundable==1) || (roundable==0))
1831
+ {
1832
+ expm1_direct_td(&expm1h_sup, &expm1m_sup, &expm1l_sup, x_sup, xSqHalfh_sup, xSqHalfl_sup, xSqh_sup, xSql_sup, expoX_sup);
1833
+
1834
+ RoundUpwards3(&restemp_sup,expm1h_sup, expm1m_sup, expm1l_sup);
1835
+
1836
+ } /* Accurate phase launched */
1837
+ ASSIGN_LOW(res,restemp_inf);
1838
+ ASSIGN_UP(res,restemp_sup);
1839
+ return res;
1840
+ }
1841
+
1842
+
1843
+ /* Test if we have |x| <= 1/4-1/2ulp(1/4) for knowing if we use exp(x) or approximate directly */
1844
+
1845
+ if (xIntHi_inf < DIRECTINTERVALBOUND) {
1846
+ /* We approximate expm1 directly after a range reduction as follows
1847
+
1848
+ expm1(x) = (expm1(x/2) + 2) * expm1(x/2)
1849
+
1850
+ We perform the range reduction in such a way that finally |x| < 1/32
1851
+ */
1852
+
1853
+ /* Extract the exponent of |x| and add 5 (2^5 = 32) */
1854
+ expoX_inf = ((xIntHi_inf & 0x7ff00000) >> 20) - (1023 - 5);
1855
+
1856
+ /* If this particularily biased exponent expoX is negative, we are already less than 1/32 */
1857
+ if (expoX_inf >= 0) {
1858
+ /* If we are here, we must perform range reduction */
1859
+
1860
+
1861
+ /* We multiply x by 2^(-expoX-1) by bit manipulation
1862
+ x cannot be denormalized so there is no danger
1863
+ */
1864
+ xdb_inf.i[HI] += (-expoX_inf-1) << 20;
1865
+
1866
+ /* We reassign the new x and maintain xIntHi */
1867
+
1868
+ xIntHi_inf = xdb_inf.i[HI] & 0x7fffffff;
1869
+ x_inf = xdb_inf.d;
1870
+ }
1871
+
1872
+ /* Here, we have always |x| < 1/32 */
1873
+
1874
+
1875
+ /* Double precision evaluation steps and one double-double step */
1876
+
1877
+ Mul12(&xSqh_inf,&xSql_inf,x_inf,x_inf);
1878
+
1879
+ #if defined(PROCESSOR_HAS_FMA) && !defined(AVOID_FMA)
1880
+ middlePoly_inf = FMA(quickDirectpolyC5h,x_inf,quickDirectpolyC4h);
1881
+ #else
1882
+ middlePoly_inf = quickDirectpolyC4h + x_inf * quickDirectpolyC5h;
1883
+ #endif
1884
+
1885
+ doublePoly_inf = middlePoly_inf;
1886
+
1887
+ /* Special path: for small |x| we can truncate the polynomial */
1888
+
1889
+ if (xIntHi_inf > SPECIALINTERVALBOUND) {
1890
+
1891
+ #if defined(PROCESSOR_HAS_FMA) && !defined(AVOID_FMA)
1892
+ highPoly_inf = FMA(FMA(FMA(quickDirectpolyC9h ,x_inf,quickDirectpolyC8h),x_inf,
1893
+ quickDirectpolyC7h),x_inf,quickDirectpolyC6h);
1894
+ #else
1895
+ highPoly_inf = quickDirectpolyC6h + x_inf * (quickDirectpolyC7h + x_inf * (
1896
+ quickDirectpolyC8h + x_inf * quickDirectpolyC9h));
1897
+ #endif
1898
+
1899
+ highPolyWithSquare_inf = xSqh_inf * highPoly_inf;
1900
+
1901
+ doublePoly_inf = middlePoly_inf + highPolyWithSquare_inf;
1902
+
1903
+ }
1904
+
1905
+ /* Double-double evaluation steps */
1906
+ tt1h_inf = x_inf * doublePoly_inf;
1907
+
1908
+ xSqHalfh_inf = 0.5 * xSqh_inf;
1909
+ xSqHalfl_inf = 0.5 * xSql_inf;
1910
+ Add12(t2h_inf,templ_inf,x_inf,xSqHalfh_inf);
1911
+ t2l_inf = templ_inf + xSqHalfl_inf;
1912
+
1913
+ Add12(t1h_inf,t1l_inf,quickDirectpolyC3h,tt1h_inf);
1914
+ Mul122(&xCubeh_inf,&xCubel_inf,x_inf,xSqh_inf,xSql_inf);
1915
+ Mul22(&tt3h_inf,&tt3l_inf,xCubeh_inf,xCubel_inf,t1h_inf,t1l_inf);
1916
+
1917
+ Add22(&polyh_inf,&polyl_inf,t2h_inf,t2l_inf,tt3h_inf,tt3l_inf);
1918
+
1919
+ /* Reconstruction */
1920
+
1921
+ /* If we have not performed any range reduction, we have no reconstruction to do */
1922
+ if (expoX_inf >= 0) {
1923
+ /* If we are here, we must perform reconstruction */
1924
+
1925
+ /* First reconstruction step */
1926
+ Add12(r1h_inf,r1t_inf,2,polyh_inf);
1927
+ r1l_inf = r1t_inf + polyl_inf;
1928
+ Mul22(&rr1h_inf,&rr1l_inf,r1h_inf,r1l_inf,polyh_inf,polyl_inf);
1929
+
1930
+ if (expoX_inf >= 1) {
1931
+
1932
+ /* Second reconstruction step */
1933
+ Add12(r2h_inf,r2t_inf,2,rr1h_inf);
1934
+ r2l_inf = r2t_inf + rr1l_inf;
1935
+ Mul22(&rr2h_inf,&rr2l_inf,r2h_inf,r2l_inf,rr1h_inf,rr1l_inf);
1936
+
1937
+ if (expoX_inf >= 2) {
1938
+
1939
+ /* Third reconstruction step */
1940
+ Add12(r3h_inf,r3t_inf,2,rr2h_inf);
1941
+ r3l_inf = r3t_inf + rr2l_inf;
1942
+ Mul22(&rr3h_inf,&rr3l_inf,r3h_inf,r3l_inf,rr2h_inf,rr2l_inf);
1943
+
1944
+ /* expoX may be maximally 2 */
1945
+
1946
+ expm1h_inf = rr3h_inf;
1947
+ expm1m_inf = rr3l_inf;
1948
+
1949
+ } else {
1950
+ expm1h_inf = rr2h_inf;
1951
+ expm1m_inf = rr2l_inf;
1952
+ }
1953
+
1954
+ } else {
1955
+ expm1h_inf = rr1h_inf;
1956
+ expm1m_inf = rr1l_inf;
1957
+ }
1958
+
1959
+ } else {
1960
+ expm1h_inf = polyh_inf;
1961
+ expm1m_inf = polyl_inf;
1962
+ }
1963
+
1964
+ /* Rounding test */
1965
+ infDone=1;
1966
+ TEST_AND_COPY_RD(roundable,restemp_inf,expm1h_inf, expm1m_inf, ROUNDCSTDIRECTRD);
1967
+ if(roundable==0)
1968
+ {
1969
+ expm1_direct_td(&expm1h_inf, &expm1m_inf, &expm1l_inf, x_inf, xSqHalfh_inf, xSqHalfl_inf, xSqh_inf, xSql_inf, expoX_inf);
1970
+
1971
+ RoundDownwards3(&restemp_inf,expm1h_inf, expm1m_inf, expm1l_inf);
1972
+
1973
+ } /* Accurate phase launched */
1974
+
1975
+ }
1976
+
1977
+ /* Test if we have |x| <= 1/4-1/2ulp(1/4) for knowing if we use exp(x) or approximate directly */
1978
+
1979
+ if (xIntHi_sup < DIRECTINTERVALBOUND) {
1980
+ /* We approximate expm1 directly after a range reduction as follows
1981
+
1982
+ expm1(x) = (expm1(x/2) + 2) * expm1(x/2)
1983
+
1984
+ We perform the range reduction in such a way that finally |x| < 1/32
1985
+ */
1986
+
1987
+ /* Extract the exponent of |x| and add 5 (2^5 = 32) */
1988
+ expoX_sup = ((xIntHi_sup & 0x7ff00000) >> 20) - (1023 - 5);
1989
+
1990
+ /* If this particularily biased exponent expoX is negative, we are already less than 1/32 */
1991
+ if (expoX_sup >= 0) {
1992
+ /* If we are here, we must perform range reduction */
1993
+
1994
+
1995
+ /* We multiply x by 2^(-expoX-1) by bit manipulation
1996
+ x cannot be denormalized so there is no danger
1997
+ */
1998
+ xdb_sup.i[HI] += (-expoX_sup-1) << 20;
1999
+
2000
+ /* We reassign the new x and maintain xIntHi */
2001
+
2002
+ xIntHi_sup = xdb_sup.i[HI] & 0x7fffffff;
2003
+ x_sup = xdb_sup.d;
2004
+ }
2005
+
2006
+ /* Here, we have always |x| < 1/32 */
2007
+
2008
+
2009
+ /* Double precision evaluation steps and one double-double step */
2010
+
2011
+ Mul12(&xSqh_sup,&xSql_sup,x_sup,x_sup);
2012
+
2013
+ #if defined(PROCESSOR_HAS_FMA) && !defined(AVOID_FMA)
2014
+ middlePoly_sup = FMA(quickDirectpolyC5h,x_sup,quickDirectpolyC4h);
2015
+ #else
2016
+ middlePoly_sup = quickDirectpolyC4h + x_sup * quickDirectpolyC5h;
2017
+ #endif
2018
+
2019
+ doublePoly_sup = middlePoly_sup;
2020
+
2021
+ /* Special path: for small |x| we can truncate the polynomial */
2022
+
2023
+ if (xIntHi_sup > SPECIALINTERVALBOUND) {
2024
+
2025
+ #if defined(PROCESSOR_HAS_FMA) && !defined(AVOID_FMA)
2026
+ highPoly_sup = FMA(FMA(FMA(quickDirectpolyC9h ,x_sup,quickDirectpolyC8h),x_sup,
2027
+ quickDirectpolyC7h),x_sup,quickDirectpolyC6h);
2028
+ #else
2029
+ highPoly_sup = quickDirectpolyC6h + x_sup * (quickDirectpolyC7h + x_sup * (
2030
+ quickDirectpolyC8h + x_sup * quickDirectpolyC9h));
2031
+ #endif
2032
+
2033
+ highPolyWithSquare_sup = xSqh_sup * highPoly_sup;
2034
+
2035
+ doublePoly_sup = middlePoly_sup + highPolyWithSquare_sup;
2036
+
2037
+ }
2038
+
2039
+ /* Double-double evaluation steps */
2040
+ tt1h_sup = x_sup * doublePoly_sup;
2041
+
2042
+ xSqHalfh_sup = 0.5 * xSqh_sup;
2043
+ xSqHalfl_sup = 0.5 * xSql_sup;
2044
+ Add12(t2h_sup,templ_sup,x_sup,xSqHalfh_sup);
2045
+ t2l_sup = templ_sup + xSqHalfl_sup;
2046
+
2047
+ Add12(t1h_sup,t1l_sup,quickDirectpolyC3h,tt1h_sup);
2048
+ Mul122(&xCubeh_sup,&xCubel_sup,x_sup,xSqh_sup,xSql_sup);
2049
+ Mul22(&tt3h_sup,&tt3l_sup,xCubeh_sup,xCubel_sup,t1h_sup,t1l_sup);
2050
+
2051
+ Add22(&polyh_sup,&polyl_sup,t2h_sup,t2l_sup,tt3h_sup,tt3l_sup);
2052
+
2053
+ /* Reconstruction */
2054
+
2055
+ /* If we have not performed any range reduction, we have no reconstruction to do */
2056
+ if (expoX_sup >= 0) {
2057
+ /* If we are here, we must perform reconstruction */
2058
+
2059
+ /* First reconstruction step */
2060
+ Add12(r1h_sup,r1t_sup,2,polyh_sup);
2061
+ r1l_sup = r1t_sup + polyl_sup;
2062
+ Mul22(&rr1h_sup,&rr1l_sup,r1h_sup,r1l_sup,polyh_sup,polyl_sup);
2063
+
2064
+ if (expoX_sup >= 1) {
2065
+
2066
+ /* Second reconstruction step */
2067
+ Add12(r2h_sup,r2t_sup,2,rr1h_sup);
2068
+ r2l_sup = r2t_sup + rr1l_sup;
2069
+ Mul22(&rr2h_sup,&rr2l_sup,r2h_sup,r2l_sup,rr1h_sup,rr1l_sup);
2070
+
2071
+ if (expoX_sup >= 2) {
2072
+
2073
+ /* Third reconstruction step */
2074
+ Add12(r3h_sup,r3t_sup,2,rr2h_sup);
2075
+ r3l_sup = r3t_sup + rr2l_sup;
2076
+ Mul22(&rr3h_sup,&rr3l_sup,r3h_sup,r3l_sup,rr2h_sup,rr2l_sup);
2077
+
2078
+ /* expoX may be maximally 2 */
2079
+
2080
+ expm1h_sup = rr3h_sup;
2081
+ expm1m_sup = rr3l_sup;
2082
+
2083
+ } else {
2084
+ expm1h_sup = rr2h_sup;
2085
+ expm1m_sup = rr2l_sup;
2086
+ }
2087
+
2088
+ } else {
2089
+ expm1h_sup = rr1h_sup;
2090
+ expm1m_sup = rr1l_sup;
2091
+ }
2092
+
2093
+ } else {
2094
+ expm1h_sup = polyh_sup;
2095
+ expm1m_sup = polyl_sup;
2096
+ }
2097
+
2098
+ /* Rounding test */
2099
+ supDone=1;
2100
+ TEST_AND_COPY_RU(roundable,restemp_sup,expm1h_sup, expm1m_sup, ROUNDCSTDIRECTRD);
2101
+ if(roundable==0)
2102
+ {
2103
+ expm1_direct_td(&expm1h_sup, &expm1m_sup, &expm1l_sup, x_sup, xSqHalfh_sup, xSqHalfl_sup, xSqh_sup, xSql_sup, expoX_sup);
2104
+
2105
+ RoundUpwards3(&restemp_sup,expm1h_sup, expm1m_sup, expm1l_sup);
2106
+
2107
+ } /* Accurate phase launched */
2108
+
2109
+ }
2110
+ if((infDone==0) && (supDone==0))
2111
+ {
2112
+ /* If we are here, we can use expm1(x) = exp(x) - 1 */
2113
+
2114
+ /* Range reduction - exact part: compute k as double and as int */
2115
+
2116
+ xMultLog2InvMult2L_inf = x_inf * log2InvMult2L;
2117
+ xMultLog2InvMult2L_sup = x_sup * log2InvMult2L;
2118
+ shiftedXMult_inf = xMultLog2InvMult2L_inf + shiftConst;
2119
+ shiftedXMult_sup = xMultLog2InvMult2L_sup + shiftConst;
2120
+ kd_inf = shiftedXMult_inf - shiftConst;
2121
+ kd_sup = shiftedXMult_sup - shiftConst;
2122
+ shiftedXMultdb_inf.d = shiftedXMult_inf;
2123
+ shiftedXMultdb_sup.d = shiftedXMult_sup;
2124
+ k_inf = shiftedXMultdb_inf.i[LO];
2125
+ k_sup = shiftedXMultdb_sup.i[LO];
2126
+ M_inf = k_inf >> 12;
2127
+ M_sup = k_sup >> 12;
2128
+ index1_inf = k_inf & INDEXMASK1;
2129
+ index1_sup = k_sup & INDEXMASK1;
2130
+ index2_inf = (k_inf & INDEXMASK2) >> 6;
2131
+ index2_sup = (k_sup & INDEXMASK2) >> 6;
2132
+
2133
+
2134
+ /* Range reduction - part affected by error - must be redone in accurate phase */
2135
+ Mul12(&s1_inf,&s2_inf,msLog2Div2Lh,kd_inf);
2136
+ Mul12(&s1_sup,&s2_sup,msLog2Div2Lh,kd_sup);
2137
+ s3_inf = kd_inf * msLog2Div2Lm;
2138
+ s3_sup = kd_sup * msLog2Div2Lm;
2139
+ s4_inf = s2_inf + s3_inf;
2140
+ s4_sup = s2_sup + s3_sup;
2141
+ s5_inf = x_inf + s1_inf;
2142
+ s5_sup = x_sup + s1_sup;
2143
+ Add12Cond(rh_inf,rm_inf,s5_inf,s4_inf);
2144
+ Add12Cond(rh_sup,rm_sup,s5_sup,s4_sup);
2145
+
2146
+
2147
+ /* Table reads - read only two double-doubles by now */
2148
+ tbl1h_inf = twoPowerIndex1[index1_inf].hi;
2149
+ tbl1h_sup = twoPowerIndex1[index1_sup].hi;
2150
+ tbl1m_inf = twoPowerIndex1[index1_inf].mi;
2151
+ tbl1m_sup = twoPowerIndex1[index1_sup].mi;
2152
+ tbl2h_inf = twoPowerIndex2[index2_inf].hi;
2153
+ tbl2h_sup = twoPowerIndex2[index2_sup].hi;
2154
+ tbl2m_inf = twoPowerIndex2[index2_inf].mi;
2155
+ tbl2m_sup = twoPowerIndex2[index2_sup].mi;
2156
+
2157
+ /* Quick phase starts here */
2158
+
2159
+ rhSquare_inf = rh_inf * rh_inf;
2160
+ rhSquare_sup = rh_sup * rh_sup;
2161
+ rhC3_inf = quickCommonpolyC3h * rh_inf;
2162
+ rhC3_sup = quickCommonpolyC3h * rh_sup;
2163
+
2164
+ rhSquareHalf_inf = 0.5 * rhSquare_inf;
2165
+ rhSquareHalf_sup = 0.5 * rhSquare_sup;
2166
+
2167
+ monomialCube_inf = rhC3_inf * rhSquare_inf;
2168
+ monomialCube_sup = rhC3_sup * rhSquare_sup;
2169
+ rhFour_inf = rhSquare_inf * rhSquare_inf;
2170
+ rhFour_sup = rhSquare_sup * rhSquare_sup;
2171
+
2172
+ monomialFour_inf = quickCommonpolyC4h * rhFour_inf;
2173
+ monomialFour_sup = quickCommonpolyC4h * rhFour_sup;
2174
+ highPoly_inf = monomialCube_inf + monomialFour_inf;
2175
+ highPoly_sup = monomialCube_sup + monomialFour_sup;
2176
+ highPolyWithSquare_inf = rhSquareHalf_inf + highPoly_inf;
2177
+ highPolyWithSquare_sup = rhSquareHalf_sup + highPoly_sup;
2178
+
2179
+ /* Reconstruction: integration of table values */
2180
+
2181
+ Mul22(&tablesh_inf,&tablesl_inf,tbl1h_inf,tbl1m_inf,tbl2h_inf,tbl2m_inf);
2182
+ Mul22(&tablesh_sup,&tablesl_sup,tbl1h_sup,tbl1m_sup,tbl2h_sup,tbl2m_sup);
2183
+
2184
+ t8_inf = rm_inf + highPolyWithSquare_inf;
2185
+ t8_sup = rm_sup + highPolyWithSquare_sup;
2186
+ t9_inf = rh_inf + t8_inf;
2187
+ t9_sup = rh_sup + t8_sup;
2188
+
2189
+ t10_inf = tablesh_inf * t9_inf;
2190
+ t10_sup = tablesh_sup * t9_sup;
2191
+
2192
+ Add12(t11_inf,t12_inf,tablesh_inf,t10_inf);
2193
+ Add12(t11_sup,t12_sup,tablesh_sup,t10_sup);
2194
+ t13_inf = t12_inf + tablesl_inf;
2195
+ t13_sup = t12_sup + tablesl_sup;
2196
+ Add12(polyTblhdb_inf.d,polyTblmdb_inf.d,t11_inf,t13_inf);
2197
+ Add12(polyTblhdb_sup.d,polyTblmdb_sup.d,t11_sup,t13_sup);
2198
+
2199
+ /* Reconstruction: multiplication by 2^M */
2200
+
2201
+ /* Implement the multiplication by addition to overcome the
2202
+ problem of the non-representability of 2^1024 (M = 1024)
2203
+ This case is possible if polyTblhdb.d < 1
2204
+ */
2205
+
2206
+ polyTblhdb_inf.i[HI] += M_inf << 20;
2207
+ polyTblhdb_sup.i[HI] += M_sup << 20;
2208
+ if(polyTblmdb_inf.d!=0.0) /* predicted true, but it happens for x=-4.1588039009762204, thanks Morten */
2209
+ polyTblmdb_inf.i[HI] += M_inf << 20;
2210
+ if(polyTblmdb_sup.d!=0.0) /* predicted true, but it happens for x=-4.1588039009762204, thanks Morten */
2211
+ polyTblmdb_sup.i[HI] += M_sup << 20;
2212
+
2213
+ exph_inf = polyTblhdb_inf.d;
2214
+ exph_sup = polyTblhdb_sup.d;
2215
+ expm_inf = polyTblmdb_inf.d;
2216
+ expm_sup = polyTblmdb_sup.d;
2217
+
2218
+ /* Subtraction of 1
2219
+
2220
+ Testing if the operation is necessary is more expensive than
2221
+ performing it in any case.
2222
+
2223
+ We may cancellate at most 2 bits in the subtraction for
2224
+ arguments 1/4 <= x <= ln(2) (0.25 <= x <= 0.69)
2225
+ We must therefore use conditional Add12s
2226
+
2227
+ Since we perform a subtraction, we may not have addition overflow towards +inf
2228
+
2229
+ */
2230
+
2231
+ Add12Cond(t1_inf,t2_inf,-1,exph_inf);
2232
+ Add12Cond(t1_sup,t2_sup,-1,exph_sup);
2233
+ t3_inf = t2_inf + expm_inf;
2234
+ t3_sup = t2_sup + expm_sup;
2235
+ Add12Cond(expm1h_inf,expm1m_inf,t1_inf,t3_inf);
2236
+ Add12Cond(expm1h_sup,expm1m_sup,t1_sup,t3_sup);
2237
+
2238
+
2239
+ /* Rounding test */
2240
+ TEST_AND_COPY_RDRU_EXPM1(roundable,res_inf,expm1h_inf, expm1m_inf, res_sup,expm1h_sup, expm1m_sup, ROUNDCSTCOMMONRD);
2241
+ if((roundable==2) || (roundable==0))
2242
+ {
2243
+ /* Rest of argument reduction for accurate phase */
2244
+
2245
+ Mul133(&msLog2Div2LMultKh_inf,&msLog2Div2LMultKm_inf,&msLog2Div2LMultKl_inf,kd_inf,msLog2Div2Lh,msLog2Div2Lm,msLog2Div2Ll);
2246
+ t1_inf = x_inf + msLog2Div2LMultKh_inf;
2247
+ Add12Cond(rh_inf,t2_inf,t1_inf,msLog2Div2LMultKm_inf);
2248
+ Add12Cond(rm_inf,rl_inf,t2_inf,msLog2Div2LMultKl_inf);
2249
+
2250
+ /* Table reads for accurate phase */
2251
+ tbl1l_inf = twoPowerIndex1[index1_inf].lo;
2252
+ tbl2l_inf = twoPowerIndex2[index2_inf].lo;
2253
+
2254
+ /* Call accurate phase */
2255
+ expm1_common_td(&expm1h_inf, &expm1m_inf, &expm1l_inf, rh_inf, rm_inf, rl_inf, tbl1h_inf, tbl1m_inf, tbl1l_inf, tbl2h_inf, tbl2m_inf, tbl2l_inf, M_inf);
2256
+
2257
+ /* Final rounding */
2258
+
2259
+ RoundDownwards3(&res_inf,expm1h_inf, expm1m_inf, expm1l_inf);
2260
+ } /* Accurate phase launched */
2261
+ if((roundable==1) || (roundable==0))
2262
+ {
2263
+ /* Rest of argument reduction for accurate phase */
2264
+ Mul133(&msLog2Div2LMultKh_sup,&msLog2Div2LMultKm_sup,&msLog2Div2LMultKl_sup,kd_sup,msLog2Div2Lh,msLog2Div2Lm,msLog2Div2Ll);
2265
+ t1_sup = x_sup + msLog2Div2LMultKh_sup;
2266
+ Add12Cond(rh_sup,t2_sup,t1_sup,msLog2Div2LMultKm_sup);
2267
+ Add12Cond(rm_sup,rl_sup,t2_sup,msLog2Div2LMultKl_sup);
2268
+
2269
+ /* Table reads for accurate phase */
2270
+ tbl1l_sup = twoPowerIndex1[index1_sup].lo;
2271
+ tbl2l_sup = twoPowerIndex2[index2_sup].lo;
2272
+
2273
+ /* Call accurate phase */
2274
+ expm1_common_td(&expm1h_sup, &expm1m_sup, &expm1l_sup, rh_sup, rm_sup, rl_sup, tbl1h_sup, tbl1m_sup, tbl1l_sup, tbl2h_sup, tbl2m_sup, tbl2l_sup, M_sup);
2275
+
2276
+ /* Final rounding */
2277
+
2278
+ RoundUpwards3(&res_sup,expm1h_sup, expm1m_sup, expm1l_sup);
2279
+ } /* Accurate phase launched */
2280
+
2281
+ ASSIGN_LOW(res,res_inf);
2282
+ ASSIGN_UP(res,res_sup);
2283
+ return res;
2284
+ }
2285
+ if((supDone==1))
2286
+ {
2287
+ /* If we are here, we can use expm1(x) = exp(x) - 1 */
2288
+
2289
+ /* Range reduction - exact part: compute k as double and as int */
2290
+
2291
+ xMultLog2InvMult2L_inf = x_inf * log2InvMult2L;
2292
+ shiftedXMult_inf = xMultLog2InvMult2L_inf + shiftConst;
2293
+ kd_inf = shiftedXMult_inf - shiftConst;
2294
+ shiftedXMultdb_inf.d = shiftedXMult_inf;
2295
+ k_inf = shiftedXMultdb_inf.i[LO];
2296
+ M_inf = k_inf >> 12;
2297
+ index1_inf = k_inf & INDEXMASK1;
2298
+ index2_inf = (k_inf & INDEXMASK2) >> 6;
2299
+
2300
+
2301
+ /* Range reduction - part affected by error - must be redone in accurate phase */
2302
+ Mul12(&s1_inf,&s2_inf,msLog2Div2Lh,kd_inf);
2303
+ s3_inf = kd_inf * msLog2Div2Lm;
2304
+ s4_inf = s2_inf + s3_inf;
2305
+ s5_inf = x_inf + s1_inf;
2306
+ Add12Cond(rh_inf,rm_inf,s5_inf,s4_inf);
2307
+
2308
+
2309
+ /* Table reads - read only two double-doubles by now */
2310
+ tbl1h_inf = twoPowerIndex1[index1_inf].hi;
2311
+ tbl1m_inf = twoPowerIndex1[index1_inf].mi;
2312
+ tbl2h_inf = twoPowerIndex2[index2_inf].hi;
2313
+ tbl2m_inf = twoPowerIndex2[index2_inf].mi;
2314
+
2315
+ /* Quick phase starts here */
2316
+
2317
+ rhSquare_inf = rh_inf * rh_inf;
2318
+ rhC3_inf = quickCommonpolyC3h * rh_inf;
2319
+
2320
+ rhSquareHalf_inf = 0.5 * rhSquare_inf;
2321
+
2322
+ monomialCube_inf = rhC3_inf * rhSquare_inf;
2323
+ rhFour_inf = rhSquare_inf * rhSquare_inf;
2324
+
2325
+ monomialFour_inf = quickCommonpolyC4h * rhFour_inf;
2326
+ highPoly_inf = monomialCube_inf + monomialFour_inf;
2327
+ highPolyWithSquare_inf = rhSquareHalf_inf + highPoly_inf;
2328
+
2329
+ /* Reconstruction: integration of table values */
2330
+
2331
+ Mul22(&tablesh_inf,&tablesl_inf,tbl1h_inf,tbl1m_inf,tbl2h_inf,tbl2m_inf);
2332
+
2333
+ t8_inf = rm_inf + highPolyWithSquare_inf;
2334
+ t9_inf = rh_inf + t8_inf;
2335
+
2336
+ t10_inf = tablesh_inf * t9_inf;
2337
+
2338
+ Add12(t11_inf,t12_inf,tablesh_inf,t10_inf);
2339
+ t13_inf = t12_inf + tablesl_inf;
2340
+ Add12(polyTblhdb_inf.d,polyTblmdb_inf.d,t11_inf,t13_inf);
2341
+
2342
+ /* Reconstruction: multiplication by 2^M */
2343
+
2344
+ /* Implement the multiplication by addition to overcome the
2345
+ problem of the non-representability of 2^1024 (M = 1024)
2346
+ This case is possible if polyTblhdb.d < 1
2347
+ */
2348
+
2349
+ polyTblhdb_inf.i[HI] += M_inf << 20;
2350
+ if(polyTblmdb_inf.d!=0.0) /* predicted true, but it happens for x=-4.1588039009762204, thanks Morten */
2351
+ polyTblmdb_inf.i[HI] += M_inf << 20;
2352
+
2353
+ exph_inf = polyTblhdb_inf.d;
2354
+ expm_inf = polyTblmdb_inf.d;
2355
+
2356
+ /* Subtraction of 1
2357
+
2358
+ Testing if the operation is necessary is more expensive than
2359
+ performing it in any case.
2360
+
2361
+ We may cancellate at most 2 bits in the subtraction for
2362
+ arguments 1/4 <= x <= ln(2) (0.25 <= x <= 0.69)
2363
+ We must therefore use conditional Add12s
2364
+
2365
+ Since we perform a subtraction, we may not have addition overflow towards +inf
2366
+
2367
+ */
2368
+
2369
+ Add12Cond(t1_inf,t2_inf,-1,exph_inf);
2370
+ t3_inf = t2_inf + expm_inf;
2371
+ Add12Cond(expm1h_inf,expm1m_inf,t1_inf,t3_inf);
2372
+
2373
+
2374
+ /* Rounding test */
2375
+ TEST_AND_COPY_RD(roundable,res_inf,expm1h_inf, expm1m_inf, ROUNDCSTCOMMONRD);
2376
+ if(roundable==0)
2377
+ {
2378
+ /* Rest of argument reduction for accurate phase */
2379
+
2380
+ Mul133(&msLog2Div2LMultKh_inf,&msLog2Div2LMultKm_inf,&msLog2Div2LMultKl_inf,kd_inf,msLog2Div2Lh,msLog2Div2Lm,msLog2Div2Ll);
2381
+ t1_inf = x_inf + msLog2Div2LMultKh_inf;
2382
+ Add12Cond(rh_inf,t2_inf,t1_inf,msLog2Div2LMultKm_inf);
2383
+ Add12Cond(rm_inf,rl_inf,t2_inf,msLog2Div2LMultKl_inf);
2384
+
2385
+ /* Table reads for accurate phase */
2386
+ tbl1l_inf = twoPowerIndex1[index1_inf].lo;
2387
+ tbl2l_inf = twoPowerIndex2[index2_inf].lo;
2388
+
2389
+ /* Call accurate phase */
2390
+ expm1_common_td(&expm1h_inf, &expm1m_inf, &expm1l_inf, rh_inf, rm_inf, rl_inf, tbl1h_inf, tbl1m_inf, tbl1l_inf, tbl2h_inf, tbl2m_inf, tbl2l_inf, M_inf);
2391
+
2392
+ /* Final rounding */
2393
+
2394
+ RoundDownwards3(&res_inf,expm1h_inf, expm1m_inf, expm1l_inf);
2395
+ } /* Accurate phase launched */
2396
+
2397
+ }
2398
+ if(infDone==1)
2399
+ {
2400
+ /* If we are here, we can use expm1(x) = exp(x) - 1 */
2401
+
2402
+ /* Range reduction - exact part: compute k as double and as int */
2403
+
2404
+ xMultLog2InvMult2L_sup = x_sup * log2InvMult2L;
2405
+ shiftedXMult_sup = xMultLog2InvMult2L_sup + shiftConst;
2406
+ kd_sup = shiftedXMult_sup - shiftConst;
2407
+ shiftedXMultdb_sup.d = shiftedXMult_sup;
2408
+ k_sup = shiftedXMultdb_sup.i[LO];
2409
+ M_sup = k_sup >> 12;
2410
+ index1_sup = k_sup & INDEXMASK1;
2411
+ index2_sup = (k_sup & INDEXMASK2) >> 6;
2412
+
2413
+
2414
+ /* Range reduction - part affected by error - must be redone in accurate phase */
2415
+ Mul12(&s1_sup,&s2_sup,msLog2Div2Lh,kd_sup);
2416
+ s3_sup = kd_sup * msLog2Div2Lm;
2417
+ s4_sup = s2_sup + s3_sup;
2418
+ s5_sup = x_sup + s1_sup;
2419
+ Add12Cond(rh_sup,rm_sup,s5_sup,s4_sup);
2420
+
2421
+
2422
+ /* Table reads - read only two double-doubles by now */
2423
+ tbl1h_sup = twoPowerIndex1[index1_sup].hi;
2424
+ tbl1m_sup = twoPowerIndex1[index1_sup].mi;
2425
+ tbl2h_sup = twoPowerIndex2[index2_sup].hi;
2426
+ tbl2m_sup = twoPowerIndex2[index2_sup].mi;
2427
+
2428
+ /* Quick phase starts here */
2429
+
2430
+ rhSquare_sup = rh_sup * rh_sup;
2431
+ rhC3_sup = quickCommonpolyC3h * rh_sup;
2432
+
2433
+ rhSquareHalf_sup = 0.5 * rhSquare_sup;
2434
+
2435
+ monomialCube_sup = rhC3_sup * rhSquare_sup;
2436
+ rhFour_sup = rhSquare_sup * rhSquare_sup;
2437
+
2438
+ monomialFour_sup = quickCommonpolyC4h * rhFour_sup;
2439
+ highPoly_sup = monomialCube_sup + monomialFour_sup;
2440
+ highPolyWithSquare_sup = rhSquareHalf_sup + highPoly_sup;
2441
+
2442
+ /* Reconstruction: integration of table values */
2443
+
2444
+ Mul22(&tablesh_sup,&tablesl_sup,tbl1h_sup,tbl1m_sup,tbl2h_sup,tbl2m_sup);
2445
+
2446
+ t8_sup = rm_sup + highPolyWithSquare_sup;
2447
+ t9_sup = rh_sup + t8_sup;
2448
+
2449
+ t10_sup = tablesh_sup * t9_sup;
2450
+
2451
+ Add12(t11_sup,t12_sup,tablesh_sup,t10_sup);
2452
+ t13_sup = t12_sup + tablesl_sup;
2453
+ Add12(polyTblhdb_sup.d,polyTblmdb_sup.d,t11_sup,t13_sup);
2454
+
2455
+ /* Reconstruction: multiplication by 2^M */
2456
+
2457
+ /* Implement the multiplication by addition to overcome the
2458
+ problem of the non-representability of 2^1024 (M = 1024)
2459
+ This case is possible if polyTblhdb.d < 1
2460
+ */
2461
+
2462
+ polyTblhdb_sup.i[HI] += M_sup << 20;
2463
+ if(polyTblmdb_sup.d!=0.0) /* predicted true, but it happens for x=-4.1588039009762204, thanks Morten */
2464
+ polyTblmdb_sup.i[HI] += M_sup << 20;
2465
+
2466
+ exph_sup = polyTblhdb_sup.d;
2467
+ expm_sup = polyTblmdb_sup.d;
2468
+
2469
+ /* Subtraction of 1
2470
+
2471
+ Testing if the operation is necessary is more expensive than
2472
+ performing it in any case.
2473
+
2474
+ We may cancellate at most 2 bits in the subtraction for
2475
+ arguments 1/4 <= x <= ln(2) (0.25 <= x <= 0.69)
2476
+ We must therefore use conditional Add12s
2477
+
2478
+ Since we perform a subtraction, we may not have addition overflow towards +inf
2479
+
2480
+ */
2481
+
2482
+ Add12Cond(t1_sup,t2_sup,-1,exph_sup);
2483
+ t3_sup = t2_sup + expm_sup;
2484
+ Add12Cond(expm1h_sup,expm1m_sup,t1_sup,t3_sup);
2485
+
2486
+ /* Rounding test */
2487
+ TEST_AND_COPY_RU(roundable,res_sup,expm1h_sup, expm1m_sup, ROUNDCSTCOMMONRD);
2488
+ if(roundable==0)
2489
+ {
2490
+ /* Rest of argument reduction for accurate phase */
2491
+ Mul133(&msLog2Div2LMultKh_sup,&msLog2Div2LMultKm_sup,&msLog2Div2LMultKl_sup,kd_sup,msLog2Div2Lh,msLog2Div2Lm,msLog2Div2Ll);
2492
+ t1_sup = x_sup + msLog2Div2LMultKh_sup;
2493
+ Add12Cond(rh_sup,t2_sup,t1_sup,msLog2Div2LMultKm_sup);
2494
+ Add12Cond(rm_sup,rl_sup,t2_sup,msLog2Div2LMultKl_sup);
2495
+
2496
+ /* Table reads for accurate phase */
2497
+ tbl1l_sup = twoPowerIndex1[index1_sup].lo;
2498
+ tbl2l_sup = twoPowerIndex2[index2_sup].lo;
2499
+
2500
+ /* Call accurate phase */
2501
+ expm1_common_td(&expm1h_sup, &expm1m_sup, &expm1l_sup, rh_sup, rm_sup, rl_sup, tbl1h_sup, tbl1m_sup, tbl1l_sup, tbl2h_sup, tbl2m_sup, tbl2l_sup, M_sup);
2502
+
2503
+ /* Final rounding */
2504
+
2505
+ RoundUpwards3(&res_sup,expm1h_sup, expm1m_sup, expm1l_sup);
2506
+ } /* Accurate phase launched */
2507
+ }
2508
+
2509
+ if (infDone==1) res_inf=restemp_inf;
2510
+ if (supDone==1) res_sup=restemp_sup;
2511
+ ASSIGN_LOW(res,res_inf);
2512
+ ASSIGN_UP(res,res_sup);
2513
+ return res;
2514
+ }
2515
+ #endif