p1788 0.1.0

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 (57) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +8 -0
  3. data/AUTHORS +6 -0
  4. data/LICENSE +201 -0
  5. data/NOTICE +29 -0
  6. data/README.md +65 -0
  7. data/ext/libieeep1788_copy/README +3 -0
  8. data/ext/libieeep1788_copy/p1788/AUTHORS +16 -0
  9. data/ext/libieeep1788_copy/p1788/LICENSE +202 -0
  10. data/ext/libieeep1788_copy/p1788/NOTICE +14 -0
  11. data/ext/libieeep1788_copy/p1788/decoration/decoration.hpp +265 -0
  12. data/ext/libieeep1788_copy/p1788/exception/exception.hpp +302 -0
  13. data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor.hpp +3443 -0
  14. data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_bool_func_impl.hpp +608 -0
  15. data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_cancel_func_impl.hpp +229 -0
  16. data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_class_impl.hpp +526 -0
  17. data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_elem_func_impl.hpp +4533 -0
  18. data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_io_impl.hpp +1421 -0
  19. data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_mul_rev_to_pair_func_impl.hpp +347 -0
  20. data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_num_func_impl.hpp +655 -0
  21. data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_rec_bool_func_impl.hpp +146 -0
  22. data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_rec_overlap_impl.hpp +188 -0
  23. data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_rev_func_impl.hpp +1674 -0
  24. data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_set_op_impl.hpp +216 -0
  25. data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_setup_func_impl.hpp +68 -0
  26. data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_util_func_impl.hpp +135 -0
  27. data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_validation_func_impl.hpp +93 -0
  28. data/ext/libieeep1788_copy/p1788/infsup/base_interval.hpp +1529 -0
  29. data/ext/libieeep1788_copy/p1788/infsup/base_interval_bool_func_impl.hpp +481 -0
  30. data/ext/libieeep1788_copy/p1788/infsup/base_interval_cancel_func_impl.hpp +126 -0
  31. data/ext/libieeep1788_copy/p1788/infsup/base_interval_elem_func_impl.hpp +1581 -0
  32. data/ext/libieeep1788_copy/p1788/infsup/base_interval_io_impl.hpp +59 -0
  33. data/ext/libieeep1788_copy/p1788/infsup/base_interval_mul_rev_to_pair_func_impl.hpp +88 -0
  34. data/ext/libieeep1788_copy/p1788/infsup/base_interval_num_func_impl.hpp +345 -0
  35. data/ext/libieeep1788_copy/p1788/infsup/base_interval_rec_bool_func_impl.hpp +92 -0
  36. data/ext/libieeep1788_copy/p1788/infsup/base_interval_rec_overlap_impl.hpp +72 -0
  37. data/ext/libieeep1788_copy/p1788/infsup/base_interval_rev_func_impl.hpp +656 -0
  38. data/ext/libieeep1788_copy/p1788/infsup/base_interval_set_op_impl.hpp +126 -0
  39. data/ext/libieeep1788_copy/p1788/infsup/decorated_interval.hpp +464 -0
  40. data/ext/libieeep1788_copy/p1788/infsup/forward_declaration.hpp +66 -0
  41. data/ext/libieeep1788_copy/p1788/infsup/interval.hpp +275 -0
  42. data/ext/libieeep1788_copy/p1788/io/io_manip.hpp +531 -0
  43. data/ext/libieeep1788_copy/p1788/overlapping/overlapping.hpp +241 -0
  44. data/ext/libieeep1788_copy/p1788/p1788.hpp +45 -0
  45. data/ext/libieeep1788_copy/p1788/reduction/reduction.hpp +341 -0
  46. data/ext/libieeep1788_copy/p1788/util/io.hpp +63 -0
  47. data/ext/libieeep1788_copy/p1788/util/mixed_type_traits.hpp +140 -0
  48. data/ext/libieeep1788_copy/p1788/util/mpfr_util.hpp +77 -0
  49. data/ext/libieeep1788_copy/p1788/util/mpfr_var.hpp +119 -0
  50. data/ext/libieeep1788_copy/p1788/util/mpfr_var_impl.hpp +382 -0
  51. data/ext/libieeep1788_copy/p1788/version.hpp +34 -0
  52. data/ext/p1788/extconf.rb +49 -0
  53. data/ext/p1788/p1788.cc +3764 -0
  54. data/lib/p1788/version.rb +4 -0
  55. data/lib/p1788.rb +25 -0
  56. data/p1788.gemspec +72 -0
  57. metadata +99 -0
@@ -0,0 +1,4533 @@
1
+ //
2
+ // libieeep1788
3
+ //
4
+ // An implementation of the preliminary IEEE P1788 standard for
5
+ // interval arithmetic
6
+ //
7
+ //
8
+ // Copyright 2013 - 2015
9
+ //
10
+ // Marco Nehmeier (nehmeier@informatik.uni-wuerzburg.de)
11
+ // Department of Computer Science,
12
+ // University of Wuerzburg, Germany
13
+ //
14
+ // Licensed under the Apache License, Version 2.0 (the "License");
15
+ // you may not use this file except in compliance with the License.
16
+ // You may obtain a copy of the License at
17
+ //
18
+ // http://www.apache.org/licenses/LICENSE-2.0
19
+ //
20
+ // Unless required by applicable law or agreed to in writing, software
21
+ // distributed under the License is distributed on an "AS IS" BASIS,
22
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23
+ // See the License for the specific language governing permissions and
24
+ // limitations under the License.
25
+
26
+ #ifndef LIBIEEEP1788_P1788_FLAVOR_INFSUP_SETBASED_MPFR_BIN_IEEE754_FLAVOR_ELEM_FUNC_IMPL_HPP
27
+ #define LIBIEEEP1788_P1788_FLAVOR_INFSUP_SETBASED_MPFR_BIN_IEEE754_FLAVOR_ELEM_FUNC_IMPL_HPP
28
+
29
+
30
+ namespace p1788
31
+ {
32
+
33
+ namespace flavor
34
+ {
35
+
36
+ namespace infsup
37
+ {
38
+
39
+ namespace setbased
40
+ {
41
+
42
+ // pos
43
+
44
+ // pos ( bare interval )
45
+ template<typename T>
46
+ typename mpfr_bin_ieee754_flavor<T>::representation
47
+ mpfr_bin_ieee754_flavor<T>::pos(mpfr_bin_ieee754_flavor<T>::representation const& x)
48
+ {
49
+ if (!is_valid(x))
50
+ return empty();
51
+
52
+ return x;
53
+ }
54
+
55
+ // pos ( bare interval ) mixed type
56
+ template<typename T>
57
+ template<typename T_>
58
+ typename mpfr_bin_ieee754_flavor<T>::representation
59
+ mpfr_bin_ieee754_flavor<T>::pos(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& x)
60
+ {
61
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
62
+
63
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x))
64
+ return empty();
65
+
66
+ return convert_hull(x);
67
+ }
68
+
69
+ // pos ( decorated interval )
70
+ template<typename T>
71
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
72
+ mpfr_bin_ieee754_flavor<T>::pos(mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
73
+ {
74
+ if (!is_valid(x) || is_nai(x))
75
+ return nai();
76
+
77
+ return x;
78
+ }
79
+
80
+ // pos ( decorated interval ) mixed type
81
+ template<typename T>
82
+ template<typename T_>
83
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
84
+ mpfr_bin_ieee754_flavor<T>::pos(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& x)
85
+ {
86
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
87
+
88
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x) || mpfr_bin_ieee754_flavor<T_>::is_nai(x))
89
+ return nai();
90
+
91
+ return convert_hull(x);
92
+ }
93
+
94
+
95
+ // neg
96
+
97
+ // neg ( bare interval )
98
+ template<typename T>
99
+ typename mpfr_bin_ieee754_flavor<T>::representation
100
+ mpfr_bin_ieee754_flavor<T>::neg(mpfr_bin_ieee754_flavor<T>::representation const& x)
101
+ {
102
+ if (!is_valid(x) || is_empty(x))
103
+ return empty();
104
+
105
+ return representation(-x.second, -x.first);
106
+ }
107
+
108
+
109
+ // neg ( bare interval ) mixed type
110
+ template<typename T>
111
+ template<typename T_>
112
+ typename mpfr_bin_ieee754_flavor<T>::representation
113
+ mpfr_bin_ieee754_flavor<T>::neg(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& x)
114
+ {
115
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
116
+
117
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x))
118
+ return empty();
119
+
120
+ return convert_hull(mpfr_bin_ieee754_flavor<T_>::neg(x));
121
+ }
122
+
123
+ // neg ( decorated interval )
124
+ template<typename T>
125
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
126
+ mpfr_bin_ieee754_flavor<T>::neg(mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
127
+ {
128
+ if (!is_valid(x) || is_nai(x))
129
+ return nai();
130
+
131
+ return representation_dec(neg(x.first), x.second);
132
+ }
133
+
134
+ // neg ( decorated interval ) mixed type
135
+ template<typename T>
136
+ template<typename T_>
137
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
138
+ mpfr_bin_ieee754_flavor<T>::neg(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& x)
139
+ {
140
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
141
+
142
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x) || mpfr_bin_ieee754_flavor<T_>::is_nai(x))
143
+ return nai();
144
+
145
+ return convert_hull(mpfr_bin_ieee754_flavor<T_>::neg(x));
146
+ }
147
+
148
+
149
+
150
+
151
+ // add
152
+
153
+ // add ( bare interval )
154
+ template<typename T>
155
+ typename mpfr_bin_ieee754_flavor<T>::representation
156
+ mpfr_bin_ieee754_flavor<T>::add(mpfr_bin_ieee754_flavor<T>::representation const& x,
157
+ mpfr_bin_ieee754_flavor<T>::representation const& y)
158
+ {
159
+ if (!is_valid(x) || !is_valid(y) || is_empty(x) || is_empty(y))
160
+ return empty();
161
+
162
+ mpfr_var::setup();
163
+
164
+ mpfr_var xl(x.first, MPFR_RNDD);
165
+ mpfr_var xu(x.second, MPFR_RNDU);
166
+
167
+ mpfr_var yl(y.first, MPFR_RNDD);
168
+ mpfr_var yu(y.second, MPFR_RNDU);
169
+
170
+
171
+ xl.subnormalize(mpfr_add(xl(), xl(), yl(), MPFR_RNDD), MPFR_RNDD);
172
+ xu.subnormalize(mpfr_add(xu(), xu(), yu(), MPFR_RNDU), MPFR_RNDU);
173
+
174
+ return representation(xl.template get<T>(MPFR_RNDD), xu.template get<T>(MPFR_RNDU));
175
+ }
176
+
177
+
178
+ // add ( bare interval ) mixed type
179
+ template<typename T>
180
+ template<typename T1, typename T2>
181
+ typename mpfr_bin_ieee754_flavor<T>::representation
182
+ mpfr_bin_ieee754_flavor<T>::add(mpfr_bin_ieee754_flavor<T>::representation_type<T1> const& x,
183
+ mpfr_bin_ieee754_flavor<T>::representation_type<T2> const& y)
184
+ {
185
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
186
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
187
+
188
+ if (!mpfr_bin_ieee754_flavor<T1>::is_valid(x) || !mpfr_bin_ieee754_flavor<T2>::is_valid(y))
189
+ return empty();
190
+
191
+ // determine max. precision
192
+ typedef typename p1788::util::max_precision_type<T,T1,T2>::type T_MAX;
193
+
194
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
195
+ // Error free for floating point inf-sup intervals due to outward rounding
196
+ return convert_hull(
197
+ mpfr_bin_ieee754_flavor<T_MAX>::add(
198
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x),
199
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(y)
200
+ )
201
+ );
202
+ }
203
+
204
+
205
+ // add ( decorated interval )
206
+ template<typename T>
207
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
208
+ mpfr_bin_ieee754_flavor<T>::add(mpfr_bin_ieee754_flavor<T>::representation_dec const& x,
209
+ mpfr_bin_ieee754_flavor<T>::representation_dec const& y)
210
+ {
211
+ if (!is_valid(x) || !is_valid(y) || is_nai(x) || is_nai(y))
212
+ return nai();
213
+
214
+ // compute bare result
215
+ representation bare = add(x.first, y.first);
216
+
217
+ // compute decoration
218
+ p1788::decoration::decoration dec = std::min(
219
+ std::min(x.second, y.second),
220
+ is_common_interval(bare) ? p1788::decoration::decoration::com :
221
+ is_empty(bare) ? p1788::decoration::decoration::trv :
222
+ p1788::decoration::decoration::dac);
223
+ return representation_dec(bare, dec);
224
+ }
225
+
226
+ // add ( decorated interval ) mixed type
227
+ template<typename T>
228
+ template<typename T1, typename T2>
229
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
230
+ mpfr_bin_ieee754_flavor<T>::add(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T1> const& x,
231
+ mpfr_bin_ieee754_flavor<T>::representation_dec_type<T2> const& y)
232
+ {
233
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
234
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
235
+
236
+ if (!mpfr_bin_ieee754_flavor<T1>::is_valid(x) || !mpfr_bin_ieee754_flavor<T2>::is_valid(y)
237
+ || mpfr_bin_ieee754_flavor<T1>::is_nai(x) || mpfr_bin_ieee754_flavor<T2>::is_nai(y))
238
+ return nai();
239
+
240
+ // determine max. precision
241
+ typedef typename p1788::util::max_precision_type<T,T1,T2>::type T_MAX;
242
+
243
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
244
+ // Error free for floating point inf-sup intervals due to outward rounding
245
+ return convert_hull(
246
+ mpfr_bin_ieee754_flavor<T_MAX>::add(
247
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x),
248
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(y)
249
+ )
250
+ );
251
+ }
252
+
253
+
254
+
255
+
256
+
257
+ // sub
258
+
259
+ // sub ( bare interval )
260
+ template<typename T>
261
+ typename mpfr_bin_ieee754_flavor<T>::representation
262
+ mpfr_bin_ieee754_flavor<T>::sub(mpfr_bin_ieee754_flavor<T>::representation const& x,
263
+ mpfr_bin_ieee754_flavor<T>::representation const& y)
264
+ {
265
+ if (!is_valid(x) || !is_valid(y) || is_empty(x) || is_empty(y))
266
+ return empty();
267
+
268
+ mpfr_var::setup();
269
+
270
+ mpfr_var xl(x.first, MPFR_RNDD);
271
+ mpfr_var xu(x.second, MPFR_RNDU);
272
+
273
+ mpfr_var yl(y.first, MPFR_RNDD);
274
+ mpfr_var yu(y.second, MPFR_RNDU);
275
+
276
+
277
+ xl.subnormalize(mpfr_sub(xl(), xl(), yu(), MPFR_RNDD), MPFR_RNDD);
278
+ xu.subnormalize(mpfr_sub(xu(), xu(), yl(), MPFR_RNDU), MPFR_RNDU);
279
+
280
+ return representation(xl.template get<T>(MPFR_RNDD), xu.template get<T>(MPFR_RNDU));
281
+ }
282
+
283
+ // sub ( bare interval ) mixed type
284
+ template<typename T>
285
+ template<typename T1, typename T2>
286
+ typename mpfr_bin_ieee754_flavor<T>::representation
287
+ mpfr_bin_ieee754_flavor<T>::sub(mpfr_bin_ieee754_flavor<T>::representation_type<T1> const& x,
288
+ mpfr_bin_ieee754_flavor<T>::representation_type<T2> const& y)
289
+ {
290
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
291
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
292
+
293
+ if (!mpfr_bin_ieee754_flavor<T1>::is_valid(x) || !mpfr_bin_ieee754_flavor<T2>::is_valid(y))
294
+ return empty();
295
+
296
+ // determine max. precision
297
+ typedef typename p1788::util::max_precision_type<T,T1,T2>::type T_MAX;
298
+
299
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
300
+ // Error free for floating point inf-sup intervals due to outward rounding
301
+ return convert_hull(
302
+ mpfr_bin_ieee754_flavor<T_MAX>::sub(
303
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x),
304
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(y)
305
+ )
306
+ );
307
+ }
308
+
309
+
310
+ // sub ( decorated interval )
311
+ template<typename T>
312
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
313
+ mpfr_bin_ieee754_flavor<T>::sub(mpfr_bin_ieee754_flavor<T>::representation_dec const& x,
314
+ mpfr_bin_ieee754_flavor<T>::representation_dec const& y)
315
+ {
316
+ if (!is_valid(x) || !is_valid(y) || is_nai(x) || is_nai(y))
317
+ return nai();
318
+
319
+ // compute bare result
320
+ representation bare = sub(x.first, y.first);
321
+
322
+ // compute decoration
323
+ p1788::decoration::decoration dec = std::min(
324
+ std::min(x.second, y.second),
325
+ is_common_interval(bare) ? p1788::decoration::decoration::com :
326
+ is_empty(bare) ? p1788::decoration::decoration::trv :
327
+ p1788::decoration::decoration::dac);
328
+ return representation_dec(bare, dec);
329
+ }
330
+
331
+ // sub ( decorated interval ) mixed type
332
+ template<typename T>
333
+ template<typename T1, typename T2>
334
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
335
+ mpfr_bin_ieee754_flavor<T>::sub(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T1> const& x,
336
+ mpfr_bin_ieee754_flavor<T>::representation_dec_type<T2> const& y)
337
+ {
338
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
339
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
340
+
341
+ if (!mpfr_bin_ieee754_flavor<T1>::is_valid(x) || !mpfr_bin_ieee754_flavor<T2>::is_valid(y)
342
+ || mpfr_bin_ieee754_flavor<T1>::is_nai(x) || mpfr_bin_ieee754_flavor<T2>::is_nai(y))
343
+ return nai();
344
+
345
+ // determine max. precision
346
+ typedef typename p1788::util::max_precision_type<T,T1,T2>::type T_MAX;
347
+
348
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
349
+ // Error free for floating point inf-sup intervals due to outward rounding
350
+ return convert_hull(
351
+ mpfr_bin_ieee754_flavor<T_MAX>::sub(
352
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x),
353
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(y)
354
+ )
355
+ );
356
+ }
357
+
358
+
359
+ // mul
360
+
361
+ // mul ( bare interval )
362
+ template<typename T>
363
+ typename mpfr_bin_ieee754_flavor<T>::representation
364
+ mpfr_bin_ieee754_flavor<T>::mul(mpfr_bin_ieee754_flavor<T>::representation const& x,
365
+ mpfr_bin_ieee754_flavor<T>::representation const& y)
366
+ {
367
+ if (!is_valid(x) || !is_valid(y) || is_empty(x) || is_empty(y))
368
+ return empty();
369
+
370
+ if (x.first == 0.0 && x.second == 0.0)
371
+ return x;
372
+
373
+ if (y.first == 0.0 && y.second == 0.0)
374
+ return y;
375
+
376
+ if (is_entire(x))
377
+ return x;
378
+
379
+ if (is_entire(y))
380
+ return y;
381
+
382
+
383
+ mpfr_var::setup();
384
+ mpfr_var l;
385
+ mpfr_var u;
386
+
387
+
388
+ if (y.second <= 0.0)
389
+ {
390
+ if (x.second <= 0.0)
391
+ {
392
+ mpfr_var xl(x.first, MPFR_RNDD);
393
+ mpfr_var xu(x.second, MPFR_RNDU);
394
+
395
+ mpfr_var yl(y.first, MPFR_RNDD);
396
+ mpfr_var yu(y.second, MPFR_RNDU);
397
+
398
+ l.subnormalize(mpfr_mul(l(), xu(), yu(), MPFR_RNDD), MPFR_RNDD);
399
+ u.subnormalize(mpfr_mul(u(), xl(), yl(), MPFR_RNDU), MPFR_RNDU);
400
+ }
401
+ else if (x.first >= 0.0)
402
+ {
403
+ mpfr_var xl(x.first, MPFR_RNDD);
404
+ mpfr_var xu(x.second, MPFR_RNDU);
405
+
406
+ mpfr_var yl(y.first, MPFR_RNDD);
407
+ mpfr_var yu(y.second, MPFR_RNDU);
408
+
409
+ l.subnormalize(mpfr_mul(l(), xu(), yl(), MPFR_RNDD), MPFR_RNDD);
410
+ u.subnormalize(mpfr_mul(u(), xl(), yu(), MPFR_RNDU), MPFR_RNDU);
411
+ }
412
+ else
413
+ {
414
+ mpfr_var xl(x.first, MPFR_RNDD);
415
+ mpfr_var xu(x.second, MPFR_RNDU);
416
+
417
+ mpfr_var yl(y.first, MPFR_RNDD);
418
+
419
+ l.subnormalize(mpfr_mul(l(), xu(), yl(), MPFR_RNDD), MPFR_RNDD);
420
+ u.subnormalize(mpfr_mul(u(), xl(), yl(), MPFR_RNDU), MPFR_RNDU);
421
+ }
422
+ }
423
+ else if (y.first >= 0.0)
424
+ {
425
+ if (x.second <= 0.0)
426
+ {
427
+ mpfr_var xl(x.first, MPFR_RNDD);
428
+ mpfr_var xu(x.second, MPFR_RNDU);
429
+
430
+ mpfr_var yl(y.first, MPFR_RNDD);
431
+ mpfr_var yu(y.second, MPFR_RNDU);
432
+
433
+ l.subnormalize(mpfr_mul(l(), xl(), yu(), MPFR_RNDD), MPFR_RNDD);
434
+ u.subnormalize(mpfr_mul(u(), xu(), yl(), MPFR_RNDU), MPFR_RNDU);
435
+ }
436
+ else if (x.first >= 0.0)
437
+ {
438
+ mpfr_var xl(x.first, MPFR_RNDD);
439
+ mpfr_var xu(x.second, MPFR_RNDU);
440
+
441
+ mpfr_var yl(y.first, MPFR_RNDD);
442
+ mpfr_var yu(y.second, MPFR_RNDU);
443
+
444
+ l.subnormalize(mpfr_mul(l(), xl(), yl(), MPFR_RNDD), MPFR_RNDD);
445
+ u.subnormalize(mpfr_mul(u(), xu(), yu(), MPFR_RNDU), MPFR_RNDU);
446
+ }
447
+ else
448
+ {
449
+ mpfr_var xl(x.first, MPFR_RNDD);
450
+ mpfr_var xu(x.second, MPFR_RNDU);
451
+
452
+ mpfr_var yu(y.second, MPFR_RNDU);
453
+
454
+ l.subnormalize(mpfr_mul(l(), xl(), yu(), MPFR_RNDD), MPFR_RNDD);
455
+ u.subnormalize(mpfr_mul(u(), xu(), yu(), MPFR_RNDU), MPFR_RNDU);
456
+ }
457
+ }
458
+ else
459
+ {
460
+ if (x.second <= 0.0)
461
+ {
462
+ mpfr_var xl(x.first, MPFR_RNDD);
463
+
464
+ mpfr_var yl(y.first, MPFR_RNDD);
465
+ mpfr_var yu(y.second, MPFR_RNDU);
466
+
467
+ l.subnormalize(mpfr_mul(l(), xl(), yu(), MPFR_RNDD), MPFR_RNDD);
468
+ u.subnormalize(mpfr_mul(u(), xl(), yl(), MPFR_RNDU), MPFR_RNDU);
469
+ }
470
+ else if (x.first >= 0.0)
471
+ {
472
+ mpfr_var xu(x.second, MPFR_RNDU);
473
+
474
+ mpfr_var yl(y.first, MPFR_RNDD);
475
+ mpfr_var yu(y.second, MPFR_RNDU);
476
+
477
+ l.subnormalize(mpfr_mul(l(), xu(), yl(), MPFR_RNDD), MPFR_RNDD);
478
+ u.subnormalize(mpfr_mul(u(), xu(), yu(), MPFR_RNDU), MPFR_RNDU);
479
+ }
480
+ else
481
+ {
482
+ mpfr_var xl(x.first, MPFR_RNDD);
483
+ mpfr_var xu(x.second, MPFR_RNDU);
484
+
485
+ mpfr_var yl(y.first, MPFR_RNDD);
486
+ mpfr_var yu(y.second, MPFR_RNDU);
487
+
488
+ mpfr_var tmp;
489
+
490
+ l.subnormalize(mpfr_mul(l(), xl(), yu(), MPFR_RNDD), MPFR_RNDD);
491
+ tmp.subnormalize(mpfr_mul(tmp(), xu(), yl(), MPFR_RNDD), MPFR_RNDD);
492
+ mpfr_min(l(), l(), tmp(), MPFR_RNDD);
493
+
494
+ u.subnormalize(mpfr_mul(u(), xl(), yl(), MPFR_RNDU), MPFR_RNDU);
495
+ tmp.subnormalize(mpfr_mul(tmp(), xu(), yu(), MPFR_RNDU), MPFR_RNDU);
496
+ mpfr_max(u(), u(), tmp(), MPFR_RNDU);
497
+ }
498
+ }
499
+
500
+ return representation(l.template get<T>(MPFR_RNDD), u.template get<T>(MPFR_RNDU));
501
+ }
502
+
503
+ // mul ( bare interval ) mixed type
504
+ template<typename T>
505
+ template<typename T1, typename T2>
506
+ typename mpfr_bin_ieee754_flavor<T>::representation
507
+ mpfr_bin_ieee754_flavor<T>::mul(mpfr_bin_ieee754_flavor<T>::representation_type<T1> const& x,
508
+ mpfr_bin_ieee754_flavor<T>::representation_type<T2> const& y)
509
+ {
510
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
511
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
512
+
513
+ if (!mpfr_bin_ieee754_flavor<T1>::is_valid(x) || !mpfr_bin_ieee754_flavor<T2>::is_valid(y))
514
+ return empty();
515
+
516
+ // determine max. precision
517
+ typedef typename p1788::util::max_precision_type<T,T1,T2>::type T_MAX;
518
+
519
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
520
+ // Error free for floating point inf-sup intervals due to outward rounding
521
+ return convert_hull(
522
+ mpfr_bin_ieee754_flavor<T_MAX>::mul(
523
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x),
524
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(y)
525
+ )
526
+ );
527
+ }
528
+
529
+
530
+ // mul ( decorated interval )
531
+ template<typename T>
532
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
533
+ mpfr_bin_ieee754_flavor<T>::mul(mpfr_bin_ieee754_flavor<T>::representation_dec const& x,
534
+ mpfr_bin_ieee754_flavor<T>::representation_dec const& y)
535
+ {
536
+ if (!is_valid(x) || !is_valid(y) || is_nai(x) || is_nai(y))
537
+ return nai();
538
+
539
+ // compute bare result
540
+ representation bare = mul(x.first, y.first);
541
+
542
+ // compute decoration
543
+ p1788::decoration::decoration dec = std::min(
544
+ std::min(x.second, y.second),
545
+ is_common_interval(bare) ? p1788::decoration::decoration::com :
546
+ is_empty(bare) ? p1788::decoration::decoration::trv :
547
+ p1788::decoration::decoration::dac);
548
+ return representation_dec(bare, dec);
549
+ }
550
+
551
+ // mul ( decorated interval ) mixed type
552
+ template<typename T>
553
+ template<typename T1, typename T2>
554
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
555
+ mpfr_bin_ieee754_flavor<T>::mul(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T1> const& x,
556
+ mpfr_bin_ieee754_flavor<T>::representation_dec_type<T2> const& y)
557
+ {
558
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
559
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
560
+
561
+ if (!mpfr_bin_ieee754_flavor<T1>::is_valid(x) || !mpfr_bin_ieee754_flavor<T2>::is_valid(y)
562
+ || mpfr_bin_ieee754_flavor<T1>::is_nai(x) || mpfr_bin_ieee754_flavor<T2>::is_nai(y))
563
+ return nai();
564
+
565
+ // determine max. precision
566
+ typedef typename p1788::util::max_precision_type<T,T1,T2>::type T_MAX;
567
+
568
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
569
+ // Error free for floating point inf-sup intervals due to outward rounding
570
+ return convert_hull(
571
+ mpfr_bin_ieee754_flavor<T_MAX>::mul(
572
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x),
573
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(y)
574
+ )
575
+ );
576
+ }
577
+
578
+
579
+ // div
580
+
581
+ // div ( bare interval )
582
+ template<typename T>
583
+ typename mpfr_bin_ieee754_flavor<T>::representation
584
+ mpfr_bin_ieee754_flavor<T>::div(mpfr_bin_ieee754_flavor<T>::representation const& x,
585
+ mpfr_bin_ieee754_flavor<T>::representation const& y)
586
+ {
587
+ if (!is_valid(x) || !is_valid(y) || is_empty(x) || is_empty(y))
588
+ return empty();
589
+
590
+ if (y.first == 0.0 && y.second == 0.0)
591
+ return empty();
592
+
593
+ if (x.first == 0.0 && x.second == 0.0)
594
+ return x;
595
+
596
+ if ((y.first < 0.0 && y.second > 0.0)
597
+ || (x.first < 0.0 && x.second > 0.0
598
+ && (y.first == 0.0 || y.second == 0.0)))
599
+ return entire();
600
+
601
+ // if ((x.second < 0.0 || x.first > 0.0) && y.first == 0.0 && y.second == 0.0)
602
+ // return empty();
603
+
604
+ mpfr_var::setup();
605
+ mpfr_var l;
606
+ mpfr_var u;
607
+
608
+ if (x.second <= 0.0)
609
+ {
610
+ if (y.second < 0.0)
611
+ {
612
+ mpfr_var xl(x.first, MPFR_RNDD);
613
+ mpfr_var xu(x.second, MPFR_RNDU);
614
+
615
+ mpfr_var yl(y.first, MPFR_RNDD);
616
+ mpfr_var yu(y.second, MPFR_RNDU);
617
+
618
+ l.subnormalize(mpfr_div(l(), xu(), yl(), MPFR_RNDD), MPFR_RNDD);
619
+ u.subnormalize(mpfr_div(u(), xl(), yu(), MPFR_RNDU), MPFR_RNDU);
620
+ }
621
+ else if (y.first > 0.0)
622
+ {
623
+ mpfr_var xl(x.first, MPFR_RNDD);
624
+ mpfr_var xu(x.second, MPFR_RNDU);
625
+
626
+ mpfr_var yl(y.first, MPFR_RNDD);
627
+ mpfr_var yu(y.second, MPFR_RNDU);
628
+
629
+ l.subnormalize(mpfr_div(l(), xl(), yl(), MPFR_RNDD), MPFR_RNDD);
630
+ u.subnormalize(mpfr_div(u(), xu(), yu(), MPFR_RNDU), MPFR_RNDU);
631
+ }
632
+ else if (y.second == 0.0)
633
+ {
634
+ mpfr_var xu(x.second, MPFR_RNDU);
635
+
636
+ mpfr_var yl(y.first, MPFR_RNDD);
637
+
638
+ l.subnormalize(mpfr_div(l(), xu(), yl(), MPFR_RNDD), MPFR_RNDD);
639
+ mpfr_set_inf(u(), +1);
640
+ }
641
+ else if (y.first == 0.0)
642
+ {
643
+ mpfr_var xu(x.second, MPFR_RNDU);
644
+
645
+ mpfr_var yu(y.second, MPFR_RNDU);
646
+
647
+ mpfr_set_inf(l(), -1);
648
+ u.subnormalize(mpfr_div(u(), xu(), yu(), MPFR_RNDU), MPFR_RNDU);
649
+ }
650
+ }
651
+ else if (x.first >= 0.0)
652
+ {
653
+ if (y.second < 0.0)
654
+ {
655
+ mpfr_var xl(x.first, MPFR_RNDD);
656
+ mpfr_var xu(x.second, MPFR_RNDU);
657
+
658
+ mpfr_var yl(y.first, MPFR_RNDD);
659
+ mpfr_var yu(y.second, MPFR_RNDU);
660
+
661
+ l.subnormalize(mpfr_div(l(), xu(), yu(), MPFR_RNDD), MPFR_RNDD);
662
+ u.subnormalize(mpfr_div(u(), xl(), yl(), MPFR_RNDU), MPFR_RNDU);
663
+ }
664
+ else if (y.first > 0.0)
665
+ {
666
+ mpfr_var xl(x.first, MPFR_RNDD);
667
+ mpfr_var xu(x.second, MPFR_RNDU);
668
+
669
+ mpfr_var yl(y.first, MPFR_RNDD);
670
+ mpfr_var yu(y.second, MPFR_RNDU);
671
+
672
+ l.subnormalize(mpfr_div(l(), xl(), yu(), MPFR_RNDD), MPFR_RNDD);
673
+ u.subnormalize(mpfr_div(u(), xu(), yl(), MPFR_RNDU), MPFR_RNDU);
674
+ }
675
+ else if (y.second == 0.0)
676
+ {
677
+ mpfr_var xl(x.first, MPFR_RNDD);
678
+
679
+ mpfr_var yl(y.first, MPFR_RNDD);
680
+
681
+ mpfr_set_inf(l(), -1);
682
+ u.subnormalize(mpfr_div(u(), xl(), yl(), MPFR_RNDU), MPFR_RNDU);
683
+ }
684
+ else if (y.first == 0.0)
685
+ {
686
+ mpfr_var xl(x.first, MPFR_RNDD);
687
+
688
+ mpfr_var yu(y.second, MPFR_RNDU);
689
+
690
+ l.subnormalize(mpfr_div(l(), xl(), yu(), MPFR_RNDD), MPFR_RNDD);
691
+ mpfr_set_inf(u(), +1);
692
+ }
693
+ }
694
+ else
695
+ {
696
+ if (y.second < 0.0)
697
+ {
698
+ mpfr_var xl(x.first, MPFR_RNDD);
699
+ mpfr_var xu(x.second, MPFR_RNDU);
700
+
701
+ mpfr_var yu(y.second, MPFR_RNDU);
702
+
703
+ l.subnormalize(mpfr_div(l(), xu(), yu(), MPFR_RNDD), MPFR_RNDD);
704
+ u.subnormalize(mpfr_div(u(), xl(), yu(), MPFR_RNDU), MPFR_RNDU);
705
+ }
706
+ else if (y.first > 0.0)
707
+ {
708
+ mpfr_var xl(x.first, MPFR_RNDD);
709
+ mpfr_var xu(x.second, MPFR_RNDU);
710
+
711
+ mpfr_var yl(y.first, MPFR_RNDD);
712
+
713
+ l.subnormalize(mpfr_div(l(), xl(), yl(), MPFR_RNDD), MPFR_RNDD);
714
+ u.subnormalize(mpfr_div(u(), xu(), yl(), MPFR_RNDU), MPFR_RNDU);
715
+ }
716
+ }
717
+
718
+ return representation(l.template get<T>(MPFR_RNDD), u.template get<T>(MPFR_RNDU));
719
+ }
720
+
721
+ // div ( bare interval ) mixed type
722
+ template<typename T>
723
+ template<typename T1, typename T2>
724
+ typename mpfr_bin_ieee754_flavor<T>::representation
725
+ mpfr_bin_ieee754_flavor<T>::div(mpfr_bin_ieee754_flavor<T>::representation_type<T1> const& x,
726
+ mpfr_bin_ieee754_flavor<T>::representation_type<T2> const& y)
727
+ {
728
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
729
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
730
+
731
+ if (!mpfr_bin_ieee754_flavor<T1>::is_valid(x) || !mpfr_bin_ieee754_flavor<T2>::is_valid(y))
732
+ return empty();
733
+
734
+ // determine max. precision
735
+ typedef typename p1788::util::max_precision_type<T,T1,T2>::type T_MAX;
736
+
737
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
738
+ // Error free for floating point inf-sup intervals due to outward rounding
739
+ return convert_hull(
740
+ mpfr_bin_ieee754_flavor<T_MAX>::div(
741
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x),
742
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(y)
743
+ )
744
+ );
745
+ }
746
+
747
+
748
+ // div ( decorated interval )
749
+ template<typename T>
750
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
751
+ mpfr_bin_ieee754_flavor<T>::div(mpfr_bin_ieee754_flavor<T>::representation_dec const& x,
752
+ mpfr_bin_ieee754_flavor<T>::representation_dec const& y)
753
+ {
754
+ if (!is_valid(x) || !is_valid(y) || is_nai(x) || is_nai(y))
755
+ return nai();
756
+
757
+ // compute bare result
758
+ representation bare = div(x.first, y.first);
759
+
760
+ // compute decoration
761
+ p1788::decoration::decoration dec = std::min(
762
+ std::min(x.second, y.second),
763
+ is_member(0.0, y) || is_empty(bare) ? p1788::decoration::decoration::trv :
764
+ is_common_interval(bare) ? p1788::decoration::decoration::com :
765
+ p1788::decoration::decoration::dac);
766
+ return representation_dec(bare, dec);
767
+ }
768
+
769
+ // div ( decorated interval ) mixed type
770
+ template<typename T>
771
+ template<typename T1, typename T2>
772
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
773
+ mpfr_bin_ieee754_flavor<T>::div(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T1> const& x,
774
+ mpfr_bin_ieee754_flavor<T>::representation_dec_type<T2> const& y)
775
+ {
776
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
777
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
778
+
779
+ if (!mpfr_bin_ieee754_flavor<T1>::is_valid(x) || !mpfr_bin_ieee754_flavor<T2>::is_valid(y)
780
+ || mpfr_bin_ieee754_flavor<T1>::is_nai(x) || mpfr_bin_ieee754_flavor<T2>::is_nai(y))
781
+ return nai();
782
+
783
+ // determine max. precision
784
+ typedef typename p1788::util::max_precision_type<T,T1,T2>::type T_MAX;
785
+
786
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
787
+ // Error free for floating point inf-sup intervals due to outward rounding
788
+ return convert_hull(
789
+ mpfr_bin_ieee754_flavor<T_MAX>::div(
790
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x),
791
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(y)
792
+ )
793
+ );
794
+ }
795
+
796
+
797
+ // recip
798
+
799
+ // recip ( bare interval )
800
+ template<typename T>
801
+ typename mpfr_bin_ieee754_flavor<T>::representation
802
+ mpfr_bin_ieee754_flavor<T>::recip(mpfr_bin_ieee754_flavor<T>::representation const& x)
803
+ {
804
+ if (!is_valid(x))
805
+ return empty();
806
+
807
+ return div(representation(1.0, 1.0), x);
808
+ }
809
+
810
+ // recip ( bare interval ) mixed type
811
+ template<typename T>
812
+ template<typename T_>
813
+ typename mpfr_bin_ieee754_flavor<T>::representation
814
+ mpfr_bin_ieee754_flavor<T>::recip(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& x)
815
+ {
816
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
817
+
818
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x))
819
+ return empty();
820
+
821
+ // determine max. precision
822
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
823
+
824
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
825
+ // Error free for floating point inf-sup intervals due to outward rounding
826
+ return convert_hull(
827
+ mpfr_bin_ieee754_flavor<T_MAX>::recip(
828
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
829
+ )
830
+ );
831
+ }
832
+
833
+
834
+ // recip ( decorated interval )
835
+ template<typename T>
836
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
837
+ mpfr_bin_ieee754_flavor<T>::recip(mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
838
+ {
839
+ if (!is_valid(x) || is_nai(x))
840
+ return nai();
841
+
842
+ // compute bare result
843
+ representation bare = recip(x.first);
844
+
845
+ // compute decoration
846
+ p1788::decoration::decoration dec = std::min(
847
+ x.second,
848
+ is_member(0.0, x) || is_empty(bare) ? p1788::decoration::decoration::trv :
849
+ is_common_interval(bare) ? p1788::decoration::decoration::com :
850
+ p1788::decoration::decoration::dac);
851
+ return representation_dec(bare, dec);
852
+ }
853
+
854
+ // recip ( decorated interval ) mixed type
855
+ template<typename T>
856
+ template<typename T_>
857
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
858
+ mpfr_bin_ieee754_flavor<T>::recip(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& x)
859
+ {
860
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
861
+
862
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x) || mpfr_bin_ieee754_flavor<T_>::is_nai(x))
863
+ return nai();
864
+
865
+ // determine max. precision
866
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
867
+
868
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
869
+ // Error free for floating point inf-sup intervals due to outward rounding
870
+ return convert_hull(
871
+ mpfr_bin_ieee754_flavor<T_MAX>::recip(
872
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
873
+ )
874
+ );
875
+ }
876
+
877
+
878
+
879
+ // sqr
880
+
881
+ // sqr ( bare interval )
882
+ template<typename T>
883
+ typename mpfr_bin_ieee754_flavor<T>::representation
884
+ mpfr_bin_ieee754_flavor<T>::sqr(mpfr_bin_ieee754_flavor<T>::representation const& x)
885
+ {
886
+ if (!is_valid(x) || is_empty(x))
887
+ return empty();
888
+
889
+ mpfr_var::setup();
890
+
891
+ if (x.first < 0.0 && x.second > 0.0)
892
+ {
893
+ mpfr_var u(std::abs(x.first) > x.second ? std::abs(x.first) : x.second, MPFR_RNDU);
894
+ u.subnormalize(mpfr_sqr(u(), u(), MPFR_RNDU), MPFR_RNDU);
895
+
896
+ return representation(0.0, u.template get<T>(MPFR_RNDU));
897
+ }
898
+
899
+ mpfr_var l(std::abs(x.first) < std::abs(x.second) ? std::abs(x.first) : std::abs(x.second), MPFR_RNDD);
900
+ mpfr_var u(std::abs(x.first) > std::abs(x.second) ? std::abs(x.first) : std::abs(x.second), MPFR_RNDU);
901
+
902
+ l.subnormalize(mpfr_sqr(l(), l(), MPFR_RNDD), MPFR_RNDD);
903
+ u.subnormalize(mpfr_sqr(u(), u(), MPFR_RNDU), MPFR_RNDU);
904
+
905
+ return representation(l.template get<T>(MPFR_RNDD), u.template get<T>(MPFR_RNDU));
906
+ }
907
+
908
+ // sqr ( bare interval ) mixed type
909
+ template<typename T>
910
+ template<typename T_>
911
+ typename mpfr_bin_ieee754_flavor<T>::representation
912
+ mpfr_bin_ieee754_flavor<T>::sqr(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& x)
913
+ {
914
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
915
+
916
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x))
917
+ return empty();
918
+
919
+ // determine max. precision
920
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
921
+
922
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
923
+ // Error free for floating point inf-sup intervals due to outward rounding
924
+ return convert_hull(
925
+ mpfr_bin_ieee754_flavor<T_MAX>::sqr(
926
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
927
+ )
928
+ );
929
+ }
930
+
931
+
932
+ // sqr ( decorated interval )
933
+ template<typename T>
934
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
935
+ mpfr_bin_ieee754_flavor<T>::sqr(mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
936
+ {
937
+ if (!is_valid(x) || is_nai(x))
938
+ return nai();
939
+
940
+ // compute bare result
941
+ representation bare = sqr(x.first);
942
+
943
+ // compute decoration
944
+ p1788::decoration::decoration dec = std::min(
945
+ x.second,
946
+ is_empty(bare) ? p1788::decoration::decoration::trv :
947
+ is_common_interval(bare) ? p1788::decoration::decoration::com :
948
+ p1788::decoration::decoration::dac);
949
+ return representation_dec(bare, dec);
950
+ }
951
+
952
+ // sqr ( decorated interval ) mixed type
953
+ template<typename T>
954
+ template<typename T_>
955
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
956
+ mpfr_bin_ieee754_flavor<T>::sqr(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& x)
957
+ {
958
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
959
+
960
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x) || mpfr_bin_ieee754_flavor<T_>::is_nai(x))
961
+ return nai();
962
+
963
+ // determine max. precision
964
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
965
+
966
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
967
+ // Error free for floating point inf-sup intervals due to outward rounding
968
+ return convert_hull(
969
+ mpfr_bin_ieee754_flavor<T_MAX>::sqr(
970
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
971
+ )
972
+ );
973
+ }
974
+
975
+
976
+
977
+
978
+ // sqrt
979
+
980
+ // sqrt ( bare interval )
981
+ template<typename T>
982
+ typename mpfr_bin_ieee754_flavor<T>::representation
983
+ mpfr_bin_ieee754_flavor<T>::sqrt(mpfr_bin_ieee754_flavor<T>::representation const& x)
984
+ {
985
+ if (!is_valid(x) || is_empty(x) || x.second < 0.0)
986
+ return empty();
987
+
988
+ mpfr_var::setup();
989
+
990
+ if (x.first < 0.0)
991
+ {
992
+ mpfr_var xu(x.second, MPFR_RNDU);
993
+
994
+ xu.subnormalize(mpfr_sqrt(xu(), xu(), MPFR_RNDU), MPFR_RNDU);
995
+
996
+ return representation(0.0, xu.template get<T>(MPFR_RNDU));
997
+ }
998
+
999
+ mpfr_var xl(x.first, MPFR_RNDD);
1000
+ mpfr_var xu(x.second, MPFR_RNDU);
1001
+
1002
+ xl.subnormalize(mpfr_sqrt(xl(), xl(), MPFR_RNDD), MPFR_RNDD);
1003
+ xu.subnormalize(mpfr_sqrt(xu(), xu(), MPFR_RNDU), MPFR_RNDU);
1004
+
1005
+ return representation(xl.template get<T>(MPFR_RNDD), xu.template get<T>(MPFR_RNDU));
1006
+ }
1007
+
1008
+ // sqrt ( bare interval ) mixed type
1009
+ template<typename T>
1010
+ template<typename T_>
1011
+ typename mpfr_bin_ieee754_flavor<T>::representation
1012
+ mpfr_bin_ieee754_flavor<T>::sqrt(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& x)
1013
+ {
1014
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1015
+
1016
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x))
1017
+ return empty();
1018
+
1019
+ // determine max. precision
1020
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
1021
+
1022
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
1023
+ // Error free for floating point inf-sup intervals due to outward rounding
1024
+ return convert_hull(
1025
+ mpfr_bin_ieee754_flavor<T_MAX>::sqrt(
1026
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
1027
+ )
1028
+ );
1029
+ }
1030
+
1031
+
1032
+ // sqrt ( decorated interval )
1033
+ template<typename T>
1034
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
1035
+ mpfr_bin_ieee754_flavor<T>::sqrt(mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
1036
+ {
1037
+ if (!is_valid(x) || is_nai(x))
1038
+ return nai();
1039
+
1040
+ // compute bare result
1041
+ representation bare = sqrt(x.first);
1042
+
1043
+ // compute decoration
1044
+ p1788::decoration::decoration dec = std::min(
1045
+ x.second,
1046
+ x.first.first < 0.0 || is_empty(bare) ? p1788::decoration::decoration::trv :
1047
+ is_common_interval(bare) ? p1788::decoration::decoration::com :
1048
+ p1788::decoration::decoration::dac);
1049
+ return representation_dec(bare, dec);
1050
+ }
1051
+
1052
+ // sqrt ( decorated interval ) mixed type
1053
+ template<typename T>
1054
+ template<typename T_>
1055
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
1056
+ mpfr_bin_ieee754_flavor<T>::sqrt(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& x)
1057
+ {
1058
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1059
+
1060
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x) || mpfr_bin_ieee754_flavor<T_>::is_nai(x))
1061
+ return nai();
1062
+
1063
+ // determine max. precision
1064
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
1065
+
1066
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
1067
+ // Error free for floating point inf-sup intervals due to outward rounding
1068
+ return convert_hull(
1069
+ mpfr_bin_ieee754_flavor<T_MAX>::sqrt(
1070
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
1071
+ )
1072
+ );
1073
+ }
1074
+
1075
+
1076
+
1077
+ // fma
1078
+
1079
+ // fma ( bare interval )
1080
+ template<typename T>
1081
+ typename mpfr_bin_ieee754_flavor<T>::representation
1082
+ mpfr_bin_ieee754_flavor<T>::fma(mpfr_bin_ieee754_flavor<T>::representation const& x,
1083
+ mpfr_bin_ieee754_flavor<T>::representation const& y,
1084
+ mpfr_bin_ieee754_flavor<T>::representation const& z)
1085
+ {
1086
+ if (!is_valid(x) || !is_valid(y) || !is_valid(z)
1087
+ || is_empty(x) || is_empty(y) || is_empty(z))
1088
+ return empty();
1089
+
1090
+ if (x.first == 0.0 && x.second == 0.0)
1091
+ return z;
1092
+
1093
+ if (y.first == 0.0 && y.second == 0.0)
1094
+ return z;
1095
+
1096
+ if (is_entire(x))
1097
+ return x;
1098
+
1099
+ if (is_entire(y))
1100
+ return y;
1101
+
1102
+
1103
+ mpfr_var::setup();
1104
+ mpfr_var l;
1105
+ mpfr_var u;
1106
+
1107
+
1108
+ if (y.second <= 0.0)
1109
+ {
1110
+ if (x.second <= 0.0)
1111
+ {
1112
+ mpfr_var xl(x.first, MPFR_RNDD);
1113
+ mpfr_var xu(x.second, MPFR_RNDU);
1114
+
1115
+ mpfr_var yl(y.first, MPFR_RNDD);
1116
+ mpfr_var yu(y.second, MPFR_RNDU);
1117
+
1118
+ mpfr_var zl(z.first, MPFR_RNDD);
1119
+ mpfr_var zu(z.second, MPFR_RNDU);
1120
+
1121
+ l.subnormalize(mpfr_fma(l(), xu(), yu(), zl(), MPFR_RNDD), MPFR_RNDD);
1122
+ u.subnormalize(mpfr_fma(u(), xl(), yl(), zu(), MPFR_RNDU), MPFR_RNDU);
1123
+ }
1124
+ else if (x.first >= 0.0)
1125
+ {
1126
+ mpfr_var xl(x.first, MPFR_RNDD);
1127
+ mpfr_var xu(x.second, MPFR_RNDU);
1128
+
1129
+ mpfr_var yl(y.first, MPFR_RNDD);
1130
+ mpfr_var yu(y.second, MPFR_RNDU);
1131
+
1132
+ mpfr_var zl(z.first, MPFR_RNDD);
1133
+ mpfr_var zu(z.second, MPFR_RNDU);
1134
+
1135
+ l.subnormalize(mpfr_fma(l(), xu(), yl(), zl(), MPFR_RNDD), MPFR_RNDD);
1136
+ u.subnormalize(mpfr_fma(u(), xl(), yu(), zu(), MPFR_RNDU), MPFR_RNDU);
1137
+ }
1138
+ else
1139
+ {
1140
+ mpfr_var xl(x.first, MPFR_RNDD);
1141
+ mpfr_var xu(x.second, MPFR_RNDU);
1142
+
1143
+ mpfr_var yl(y.first, MPFR_RNDD);
1144
+
1145
+ mpfr_var zl(z.first, MPFR_RNDD);
1146
+ mpfr_var zu(z.second, MPFR_RNDU);
1147
+
1148
+ l.subnormalize(mpfr_fma(l(), xu(), yl(), zl(), MPFR_RNDD), MPFR_RNDD);
1149
+ u.subnormalize(mpfr_fma(u(), xl(), yl(), zu(), MPFR_RNDU), MPFR_RNDU);
1150
+ }
1151
+ }
1152
+ else if (y.first >= 0.0)
1153
+ {
1154
+ if (x.second <= 0.0)
1155
+ {
1156
+ mpfr_var xl(x.first, MPFR_RNDD);
1157
+ mpfr_var xu(x.second, MPFR_RNDU);
1158
+
1159
+ mpfr_var yl(y.first, MPFR_RNDD);
1160
+ mpfr_var yu(y.second, MPFR_RNDU);
1161
+
1162
+ mpfr_var zl(z.first, MPFR_RNDD);
1163
+ mpfr_var zu(z.second, MPFR_RNDU);
1164
+
1165
+ l.subnormalize(mpfr_fma(l(), xl(), yu(), zl(), MPFR_RNDD), MPFR_RNDD);
1166
+ u.subnormalize(mpfr_fma(u(), xu(), yl(), zu(), MPFR_RNDU), MPFR_RNDU);
1167
+ }
1168
+ else if (x.first >= 0.0)
1169
+ {
1170
+ mpfr_var xl(x.first, MPFR_RNDD);
1171
+ mpfr_var xu(x.second, MPFR_RNDU);
1172
+
1173
+ mpfr_var yl(y.first, MPFR_RNDD);
1174
+ mpfr_var yu(y.second, MPFR_RNDU);
1175
+
1176
+ mpfr_var zl(z.first, MPFR_RNDD);
1177
+ mpfr_var zu(z.second, MPFR_RNDU);
1178
+
1179
+ l.subnormalize(mpfr_fma(l(), xl(), yl(), zl(), MPFR_RNDD), MPFR_RNDD);
1180
+ u.subnormalize(mpfr_fma(u(), xu(), yu(), zu(), MPFR_RNDU), MPFR_RNDU);
1181
+ }
1182
+ else
1183
+ {
1184
+ mpfr_var xl(x.first, MPFR_RNDD);
1185
+ mpfr_var xu(x.second, MPFR_RNDU);
1186
+
1187
+ mpfr_var yu(y.second, MPFR_RNDU);
1188
+
1189
+ mpfr_var zl(z.first, MPFR_RNDD);
1190
+ mpfr_var zu(z.second, MPFR_RNDU);
1191
+
1192
+ l.subnormalize(mpfr_fma(l(), xl(), yu(), zl(), MPFR_RNDD), MPFR_RNDD);
1193
+ u.subnormalize(mpfr_fma(u(), xu(), yu(), zu(), MPFR_RNDU), MPFR_RNDU);
1194
+ }
1195
+ }
1196
+ else
1197
+ {
1198
+ if (x.second <= 0.0)
1199
+ {
1200
+ mpfr_var xl(x.first, MPFR_RNDD);
1201
+
1202
+ mpfr_var yl(y.first, MPFR_RNDD);
1203
+ mpfr_var yu(y.second, MPFR_RNDU);
1204
+
1205
+ mpfr_var zl(z.first, MPFR_RNDD);
1206
+ mpfr_var zu(z.second, MPFR_RNDU);
1207
+
1208
+ l.subnormalize(mpfr_fma(l(), xl(), yu(), zl(), MPFR_RNDD), MPFR_RNDD);
1209
+ u.subnormalize(mpfr_fma(u(), xl(), yl(), zu(), MPFR_RNDU), MPFR_RNDU);
1210
+ }
1211
+ else if (x.first >= 0.0)
1212
+ {
1213
+ mpfr_var xu(x.second, MPFR_RNDU);
1214
+
1215
+ mpfr_var yl(y.first, MPFR_RNDD);
1216
+ mpfr_var yu(y.second, MPFR_RNDU);
1217
+
1218
+ mpfr_var zl(z.first, MPFR_RNDD);
1219
+ mpfr_var zu(z.second, MPFR_RNDU);
1220
+
1221
+ l.subnormalize(mpfr_fma(l(), xu(), yl(), zl(), MPFR_RNDD), MPFR_RNDD);
1222
+ u.subnormalize(mpfr_fma(u(), xu(), yu(), zu(), MPFR_RNDU), MPFR_RNDU);
1223
+ }
1224
+ else
1225
+ {
1226
+ mpfr_var xl(x.first, MPFR_RNDD);
1227
+ mpfr_var xu(x.second, MPFR_RNDU);
1228
+
1229
+ mpfr_var yl(y.first, MPFR_RNDD);
1230
+ mpfr_var yu(y.second, MPFR_RNDU);
1231
+
1232
+ mpfr_var zl(z.first, MPFR_RNDD);
1233
+ mpfr_var zu(z.second, MPFR_RNDU);
1234
+
1235
+ mpfr_var tmp;
1236
+
1237
+ l.subnormalize(mpfr_fma(l(), xl(), yu(), zl(), MPFR_RNDD), MPFR_RNDD);
1238
+ tmp.subnormalize(mpfr_fma(tmp(), xu(), yl(), zl(), MPFR_RNDD), MPFR_RNDD);
1239
+ mpfr_min(l(), l(), tmp(), MPFR_RNDD);
1240
+
1241
+ u.subnormalize(mpfr_fma(u(), xl(), yl(), zu(), MPFR_RNDU), MPFR_RNDU);
1242
+ tmp.subnormalize(mpfr_fma(tmp(), xu(), yu(), zu(), MPFR_RNDU), MPFR_RNDU);
1243
+ mpfr_max(u(), u(), tmp(), MPFR_RNDU);
1244
+ }
1245
+ }
1246
+
1247
+ return representation(l.template get<T>(MPFR_RNDD), u.template get<T>(MPFR_RNDU));
1248
+ }
1249
+
1250
+ // fma ( bare interval ) mixed type
1251
+ template<typename T>
1252
+ template<typename T1, typename T2, typename T3>
1253
+ typename mpfr_bin_ieee754_flavor<T>::representation
1254
+ mpfr_bin_ieee754_flavor<T>::fma(mpfr_bin_ieee754_flavor<T>::representation_type<T1> const& x,
1255
+ mpfr_bin_ieee754_flavor<T>::representation_type<T2> const& y,
1256
+ mpfr_bin_ieee754_flavor<T>::representation_type<T3> const& z)
1257
+ {
1258
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1259
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1260
+ static_assert(std::numeric_limits<T3>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1261
+
1262
+ if (!mpfr_bin_ieee754_flavor<T1>::is_valid(x)
1263
+ || !mpfr_bin_ieee754_flavor<T2>::is_valid(y)
1264
+ || !mpfr_bin_ieee754_flavor<T3>::is_valid(z))
1265
+ return empty();
1266
+
1267
+ // determine max. precision
1268
+ typedef typename p1788::util::max_precision_type<T,T1,T2,T3>::type T_MAX;
1269
+
1270
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
1271
+ // Error free for floating point inf-sup intervals due to outward rounding
1272
+ return convert_hull(
1273
+ mpfr_bin_ieee754_flavor<T_MAX>::fma(
1274
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x),
1275
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(y),
1276
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(z)
1277
+ )
1278
+ );
1279
+ }
1280
+
1281
+
1282
+ // fma ( decorated interval )
1283
+ template<typename T>
1284
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
1285
+ mpfr_bin_ieee754_flavor<T>::fma(mpfr_bin_ieee754_flavor<T>::representation_dec const& x,
1286
+ mpfr_bin_ieee754_flavor<T>::representation_dec const& y,
1287
+ mpfr_bin_ieee754_flavor<T>::representation_dec const& z)
1288
+ {
1289
+ if (!is_valid(x) || !is_valid(y) || !is_valid(z)
1290
+ || is_nai(x) || is_nai(y) || is_nai(z))
1291
+ return nai();
1292
+
1293
+ // compute bare result
1294
+ representation bare = fma(x.first, y.first, z.first);
1295
+
1296
+ // compute decoration
1297
+ p1788::decoration::decoration dec = std::min(
1298
+ std::min(std::min(x.second, y.second), z.second),
1299
+ is_empty(bare) ? p1788::decoration::decoration::trv :
1300
+ is_common_interval(bare) ? p1788::decoration::decoration::com :
1301
+ p1788::decoration::decoration::dac);
1302
+ return representation_dec(bare, dec);
1303
+ }
1304
+
1305
+ // fma ( decorated interval ) mixed type
1306
+ template<typename T>
1307
+ template<typename T1, typename T2, typename T3>
1308
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
1309
+ mpfr_bin_ieee754_flavor<T>::fma(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T1> const& x,
1310
+ mpfr_bin_ieee754_flavor<T>::representation_dec_type<T2> const& y,
1311
+ mpfr_bin_ieee754_flavor<T>::representation_dec_type<T3> const& z)
1312
+ {
1313
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1314
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1315
+ static_assert(std::numeric_limits<T3>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1316
+
1317
+ if (!mpfr_bin_ieee754_flavor<T1>::is_valid(x)
1318
+ || !mpfr_bin_ieee754_flavor<T2>::is_valid(y)
1319
+ || !mpfr_bin_ieee754_flavor<T3>::is_valid(z)
1320
+ || mpfr_bin_ieee754_flavor<T1>::is_nai(x)
1321
+ || mpfr_bin_ieee754_flavor<T2>::is_nai(y)
1322
+ || mpfr_bin_ieee754_flavor<T3>::is_nai(z))
1323
+ return nai();
1324
+
1325
+ // determine max. precision
1326
+ typedef typename p1788::util::max_precision_type<T,T1,T2,T3>::type T_MAX;
1327
+
1328
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
1329
+ // Error free for floating point inf-sup intervals due to outward rounding
1330
+ return convert_hull(
1331
+ mpfr_bin_ieee754_flavor<T_MAX>::fma(
1332
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x),
1333
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(y),
1334
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(z)
1335
+ )
1336
+ );
1337
+ }
1338
+
1339
+
1340
+
1341
+
1342
+ // pown
1343
+
1344
+ // pown ( bare interval )
1345
+ template<typename T>
1346
+ typename mpfr_bin_ieee754_flavor<T>::representation
1347
+ mpfr_bin_ieee754_flavor<T>::pown(mpfr_bin_ieee754_flavor<T>::representation const& x,
1348
+ int p)
1349
+ {
1350
+ if (!is_valid(x) || is_empty(x))
1351
+ return empty();
1352
+
1353
+ mpfr_var::setup();
1354
+
1355
+ // positive
1356
+ if (p > 0)
1357
+ {
1358
+ // even
1359
+ if (p % 2 == 0)
1360
+ {
1361
+ if (x.first < 0.0 && x.second > 0.0)
1362
+ {
1363
+ mpfr_var u(std::abs(x.first) > x.second ? std::abs(x.first) : x.second, MPFR_RNDU);
1364
+ u.subnormalize(mpfr_pow_si(u(), u(), p, MPFR_RNDU), MPFR_RNDU);
1365
+
1366
+ return representation(0.0, u.template get<T>(MPFR_RNDU));
1367
+ }
1368
+
1369
+ mpfr_var l(std::abs(x.first) < std::abs(x.second) ? std::abs(x.first) : std::abs(x.second), MPFR_RNDD);
1370
+ mpfr_var u(std::abs(x.first) > std::abs(x.second) ? std::abs(x.first) : std::abs(x.second), MPFR_RNDU);
1371
+
1372
+ l.subnormalize(mpfr_pow_si(l(), l(), p, MPFR_RNDD), MPFR_RNDD);
1373
+ u.subnormalize(mpfr_pow_si(u(), u(), p, MPFR_RNDU), MPFR_RNDU);
1374
+
1375
+ return representation(l.template get<T>(MPFR_RNDD), u.template get<T>(MPFR_RNDU));
1376
+ }
1377
+
1378
+ // odd
1379
+ mpfr_var l(x.first, MPFR_RNDD);
1380
+ mpfr_var u(x.second, MPFR_RNDU);
1381
+
1382
+ l.subnormalize(mpfr_pow_si(l(), l(), p, MPFR_RNDD), MPFR_RNDD);
1383
+ u.subnormalize(mpfr_pow_si(u(), u(), p, MPFR_RNDU), MPFR_RNDU);
1384
+
1385
+ return representation(l.template get<T>(MPFR_RNDD), u.template get<T>(MPFR_RNDU));
1386
+ }
1387
+
1388
+ // negative
1389
+ if (p < 0)
1390
+ {
1391
+ if (x.first == 0.0 && x.second == 0.0)
1392
+ return empty();
1393
+
1394
+ // even
1395
+ if (p % 2 == 0)
1396
+ {
1397
+ if (x.first < 0.0 && x.second > 0.0)
1398
+ {
1399
+ mpfr_var l(std::abs(x.first) > x.second ? std::abs(x.first) : x.second, MPFR_RNDU);
1400
+ l.subnormalize(mpfr_pow_si(l(), l(), p, MPFR_RNDD), MPFR_RNDD);
1401
+
1402
+ return representation(l.template get<T>(MPFR_RNDD), std::numeric_limits<T>::infinity());
1403
+ }
1404
+
1405
+ mpfr_var l(std::abs(x.first) > std::abs(x.second) ? std::abs(x.first) : std::abs(x.second), MPFR_RNDU);
1406
+ mpfr_var u(std::abs(x.first) < std::abs(x.second) ? std::abs(x.first) : std::abs(x.second), MPFR_RNDD);
1407
+
1408
+ l.subnormalize(mpfr_pow_si(l(), l(), p, MPFR_RNDD), MPFR_RNDD);
1409
+ u.subnormalize(mpfr_pow_si(u(), u(), p, MPFR_RNDU), MPFR_RNDU);
1410
+
1411
+ return representation(l.template get<T>(MPFR_RNDD), u.template get<T>(MPFR_RNDU));
1412
+ }
1413
+
1414
+
1415
+ // odd
1416
+
1417
+ if (x.first < 0.0 && x.second > 0.0)
1418
+ return entire();
1419
+
1420
+ if (x.first == 0.0)
1421
+ {
1422
+ mpfr_var l(x.second, MPFR_RNDU);
1423
+ l.subnormalize(mpfr_pow_si(l(), l(), p, MPFR_RNDD), MPFR_RNDD);
1424
+
1425
+ return representation(l.template get<T>(MPFR_RNDD), std::numeric_limits<T>::infinity());
1426
+ }
1427
+
1428
+ if (x.second == 0.0)
1429
+ {
1430
+ mpfr_var u(x.first, MPFR_RNDD);
1431
+ u.subnormalize(mpfr_pow_si(u(), u(), p, MPFR_RNDU), MPFR_RNDU);
1432
+
1433
+ return representation(-std::numeric_limits<T>::infinity(), u.template get<T>(MPFR_RNDU));
1434
+ }
1435
+
1436
+
1437
+ mpfr_var l(x.second, MPFR_RNDU);
1438
+ mpfr_var u(x.first, MPFR_RNDD);
1439
+
1440
+ l.subnormalize(mpfr_pow_si(l(), l(), p, MPFR_RNDD), MPFR_RNDD);
1441
+ u.subnormalize(mpfr_pow_si(u(), u(), p, MPFR_RNDU), MPFR_RNDU);
1442
+
1443
+ return representation(l.template get<T>(MPFR_RNDD), u.template get<T>(MPFR_RNDU));
1444
+ }
1445
+
1446
+ // p == 0.0
1447
+ return representation(1.0, 1.0);
1448
+ }
1449
+
1450
+ // pown ( bare interval ) mixed type
1451
+ template<typename T>
1452
+ template<typename T_>
1453
+ typename mpfr_bin_ieee754_flavor<T>::representation
1454
+ mpfr_bin_ieee754_flavor<T>::pown(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& x,
1455
+ int p)
1456
+ {
1457
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1458
+
1459
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x))
1460
+ return empty();
1461
+
1462
+ // determine max. precision
1463
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
1464
+
1465
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
1466
+ // Error free for floating point inf-sup intervals due to outward rounding
1467
+ return convert_hull(
1468
+ mpfr_bin_ieee754_flavor<T_MAX>::pown(
1469
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x),
1470
+ p
1471
+ )
1472
+ );
1473
+ }
1474
+
1475
+
1476
+ // pown ( decorated interval )
1477
+ template<typename T>
1478
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
1479
+ mpfr_bin_ieee754_flavor<T>::pown(mpfr_bin_ieee754_flavor<T>::representation_dec const& x,
1480
+ int p)
1481
+ {
1482
+ if (!is_valid(x) || is_nai(x))
1483
+ return nai();
1484
+
1485
+ // compute bare result
1486
+ representation bare = pown(x.first, p);
1487
+
1488
+ // compute decoration
1489
+ p1788::decoration::decoration dec = std::min(
1490
+ x.second,
1491
+ (p < 0 && is_member(0.0,x)) || is_empty(bare) ? p1788::decoration::decoration::trv :
1492
+ is_common_interval(bare) ? p1788::decoration::decoration::com :
1493
+ p1788::decoration::decoration::dac);
1494
+ return representation_dec(bare, dec);
1495
+ }
1496
+
1497
+ // pown ( decorated interval ) mixed type
1498
+ template<typename T>
1499
+ template<typename T_>
1500
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
1501
+ mpfr_bin_ieee754_flavor<T>::pown(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& x,
1502
+ int p)
1503
+ {
1504
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1505
+
1506
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x) || mpfr_bin_ieee754_flavor<T_>::is_nai(x))
1507
+ return nai();
1508
+
1509
+ // determine max. precision
1510
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
1511
+
1512
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
1513
+ // Error free for floating point inf-sup intervals due to outward rounding
1514
+ return convert_hull(
1515
+ mpfr_bin_ieee754_flavor<T_MAX>::pown(
1516
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x),
1517
+ p
1518
+ )
1519
+ );
1520
+ }
1521
+
1522
+
1523
+ // pow
1524
+
1525
+ // pow ( bare interval )
1526
+ template<typename T>
1527
+ typename mpfr_bin_ieee754_flavor<T>::representation
1528
+ mpfr_bin_ieee754_flavor<T>::pow(mpfr_bin_ieee754_flavor<T>::representation const& x,
1529
+ mpfr_bin_ieee754_flavor<T>::representation const& y)
1530
+ {
1531
+ if (!is_valid(x) || !is_valid(y) || is_empty(y))
1532
+ return empty();
1533
+
1534
+ representation xx = intersection(x, representation(0.0, std::numeric_limits<T>::infinity()));
1535
+
1536
+ if (is_empty(xx))
1537
+ return xx;
1538
+
1539
+ if (xx.second == 0.0)
1540
+ {
1541
+ if (y.second <= 0.0)
1542
+ {
1543
+ return empty();
1544
+ }
1545
+ else
1546
+ {
1547
+ return representation(0.0, 0.0);
1548
+ }
1549
+ }
1550
+
1551
+ // ab hier enthält xx werte > 0
1552
+
1553
+ mpfr_var::setup();
1554
+
1555
+ mpfr_var x_lower(xx.first == -0.0 ? 0.0 : xx.first, MPFR_RNDD);
1556
+ mpfr_var x_upper(xx.second, MPFR_RNDU);
1557
+ mpfr_var y_lower(y.first, MPFR_RNDD);
1558
+ mpfr_var y_upper(y.second, MPFR_RNDU);
1559
+
1560
+ mpfr_var z_lower;
1561
+ mpfr_var z_upper;
1562
+
1563
+ if (0.0 <= y.first)
1564
+ {
1565
+ if (xx.second <= 1.0)
1566
+ {
1567
+ // special cases: x_lower==0 && (y==[0.0] || y==[0.0,r])
1568
+
1569
+ z_lower.subnormalize(mpfr_pow(z_lower(), x_lower(), y_upper(), MPFR_RNDD), MPFR_RNDD);
1570
+ z_upper.subnormalize(mpfr_pow(z_upper(), x_upper(), y_lower(), MPFR_RNDU), MPFR_RNDU);
1571
+ }
1572
+ else if (1.0 <= xx.first)
1573
+ {
1574
+ z_lower.subnormalize(mpfr_pow(z_lower(), x_lower(), y_lower(), MPFR_RNDD), MPFR_RNDD);
1575
+ z_upper.subnormalize(mpfr_pow(z_upper(), x_upper(), y_upper(), MPFR_RNDU), MPFR_RNDU);
1576
+ }
1577
+ else // xx.first < 1 && 1 < xx.second
1578
+ {
1579
+ // special cases: x_lower==0 && (y==[0.0] || y==[0.0,r])
1580
+
1581
+ z_lower.subnormalize(mpfr_pow(z_lower(), x_lower(), y_upper(), MPFR_RNDD), MPFR_RNDD);
1582
+ z_upper.subnormalize(mpfr_pow(z_upper(), x_upper(), y_upper(), MPFR_RNDU), MPFR_RNDU);
1583
+ }
1584
+ }
1585
+ else if (y.second <= 0.0)
1586
+ {
1587
+ if (xx.second <= 1.0)
1588
+ {
1589
+ // special cases: x_lower==0 && (y==[0.0] || y==[-r,0.0])
1590
+
1591
+ z_lower.subnormalize(mpfr_pow(z_lower(), x_upper(), y_upper(), MPFR_RNDD), MPFR_RNDD);
1592
+ z_upper.subnormalize(mpfr_pow(z_upper(), x_lower(), y_lower(), MPFR_RNDU), MPFR_RNDU);
1593
+ }
1594
+ else if (1.0 <= xx.first)
1595
+ {
1596
+ z_lower.subnormalize(mpfr_pow(z_lower(), x_upper(), y_lower(), MPFR_RNDD), MPFR_RNDD);
1597
+ z_upper.subnormalize(mpfr_pow(z_upper(), x_lower(), y_upper(), MPFR_RNDU), MPFR_RNDU);
1598
+ }
1599
+ else // xx.first < 1 && 1 < xx.second
1600
+ {
1601
+ // special cases: x_lower==0 && (y==[0.0] || y==[-r,0.0])
1602
+
1603
+ z_lower.subnormalize(mpfr_pow(z_lower(), x_upper(), y_lower(), MPFR_RNDD), MPFR_RNDD);
1604
+ z_upper.subnormalize(mpfr_pow(z_upper(), x_lower(), y_lower(), MPFR_RNDU), MPFR_RNDU);
1605
+ }
1606
+ }
1607
+ else // y.first < 0 && 0 < y.second
1608
+ {
1609
+ if (xx.second <= 1.0)
1610
+ {
1611
+ // special cases: x_lower==0 && y==[-r,r]
1612
+ z_lower.subnormalize(mpfr_pow(z_lower(), x_lower(), y_upper(), MPFR_RNDD), MPFR_RNDD);
1613
+ z_upper.subnormalize(mpfr_pow(z_upper(), x_lower(), y_lower(), MPFR_RNDU), MPFR_RNDU);
1614
+ }
1615
+ else if (1.0 <= xx.first)
1616
+ {
1617
+ z_lower.subnormalize(mpfr_pow(z_lower(), x_upper(), y_lower(), MPFR_RNDD), MPFR_RNDD);
1618
+ z_upper.subnormalize(mpfr_pow(z_upper(), x_upper(), y_upper(), MPFR_RNDU), MPFR_RNDU);
1619
+ }
1620
+ else // xx.first < 1 && 1 < xx.second
1621
+ {
1622
+ // special cases: x_lower==0 && y==[-r,r]
1623
+
1624
+ mpfr_var t_lower;
1625
+ mpfr_var t_upper;
1626
+
1627
+ t_lower.subnormalize(mpfr_pow(t_lower(), x_lower(), y_upper(), MPFR_RNDD), MPFR_RNDD);
1628
+ t_upper.subnormalize(mpfr_pow(t_upper(), x_lower(), y_lower(), MPFR_RNDU), MPFR_RNDU);
1629
+
1630
+ z_lower.subnormalize(mpfr_pow(z_lower(), x_upper(), y_lower(), MPFR_RNDD), MPFR_RNDD);
1631
+ z_upper.subnormalize(mpfr_pow(z_upper(), x_upper(), y_upper(), MPFR_RNDU), MPFR_RNDU);
1632
+
1633
+ mpfr_min(z_lower(), z_lower(), t_lower(), MPFR_RNDD);
1634
+ mpfr_max(z_upper(), z_upper(), t_upper(), MPFR_RNDU);
1635
+ }
1636
+ }
1637
+
1638
+ return representation(z_lower.template get<T>(MPFR_RNDD), z_upper.template get<T>(MPFR_RNDU));
1639
+ }
1640
+
1641
+
1642
+ // pow ( bare interval ) mixed type
1643
+ template<typename T>
1644
+ template<typename T1, typename T2>
1645
+ typename mpfr_bin_ieee754_flavor<T>::representation
1646
+ mpfr_bin_ieee754_flavor<T>::pow(mpfr_bin_ieee754_flavor<T>::representation_type<T1> const& x,
1647
+ mpfr_bin_ieee754_flavor<T>::representation_type<T2> const& y)
1648
+ {
1649
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1650
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1651
+
1652
+ if (!mpfr_bin_ieee754_flavor<T1>::is_valid(x) || !mpfr_bin_ieee754_flavor<T2>::is_valid(y))
1653
+ return empty();
1654
+
1655
+ // determine max. precision
1656
+ typedef typename p1788::util::max_precision_type<T,T1,T2>::type T_MAX;
1657
+
1658
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
1659
+ // Error free for floating point inf-sup intervals due to outward rounding
1660
+ return convert_hull(
1661
+ mpfr_bin_ieee754_flavor<T_MAX>::pow(
1662
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x),
1663
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(y)
1664
+ )
1665
+ );
1666
+ }
1667
+
1668
+
1669
+ // pow ( decorated interval )
1670
+ template<typename T>
1671
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
1672
+ mpfr_bin_ieee754_flavor<T>::pow(mpfr_bin_ieee754_flavor<T>::representation_dec const& x,
1673
+ mpfr_bin_ieee754_flavor<T>::representation_dec const& y)
1674
+ {
1675
+ if (!is_valid(x) || !is_valid(y) || is_nai(x) || is_nai(y))
1676
+ return nai();
1677
+
1678
+ // compute bare result
1679
+ representation bare = pow(x.first, y.first);
1680
+
1681
+ // compute decoration
1682
+ p1788::decoration::decoration dec = std::min(
1683
+ std::min(x.second, y.second),
1684
+ x.first.first < 0.0 || (is_member(0.0, x) && y.first.first <= 0.0) || is_empty(bare) ? p1788::decoration::decoration::trv :
1685
+ is_common_interval(bare) ? p1788::decoration::decoration::com :
1686
+ p1788::decoration::decoration::dac);
1687
+ return representation_dec(bare, dec);
1688
+ }
1689
+
1690
+ // pow ( decorated interval ) mixed type
1691
+ template<typename T>
1692
+ template<typename T1, typename T2>
1693
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
1694
+ mpfr_bin_ieee754_flavor<T>::pow(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T1> const& x,
1695
+ mpfr_bin_ieee754_flavor<T>::representation_dec_type<T2> const& y)
1696
+ {
1697
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1698
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1699
+
1700
+ if (!mpfr_bin_ieee754_flavor<T1>::is_valid(x) || !mpfr_bin_ieee754_flavor<T2>::is_valid(y)
1701
+ || mpfr_bin_ieee754_flavor<T1>::is_nai(x) || mpfr_bin_ieee754_flavor<T2>::is_nai(y))
1702
+ return nai();
1703
+
1704
+ // determine max. precision
1705
+ typedef typename p1788::util::max_precision_type<T,T1,T2>::type T_MAX;
1706
+
1707
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
1708
+ // Error free for floating point inf-sup intervals due to outward rounding
1709
+ return convert_hull(
1710
+ mpfr_bin_ieee754_flavor<T_MAX>::pow(
1711
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x),
1712
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(y)
1713
+ )
1714
+ );
1715
+ }
1716
+
1717
+
1718
+
1719
+ // exp
1720
+
1721
+ // exp ( bare interval )
1722
+ template<typename T>
1723
+ typename mpfr_bin_ieee754_flavor<T>::representation
1724
+ mpfr_bin_ieee754_flavor<T>::exp(mpfr_bin_ieee754_flavor<T>::representation const& x)
1725
+ {
1726
+ if (!is_valid(x) || is_empty(x))
1727
+ return empty();
1728
+
1729
+ mpfr_var::setup();
1730
+ mpfr_var l(x.first, MPFR_RNDD);
1731
+ mpfr_var u(x.second, MPFR_RNDU);
1732
+
1733
+ l.subnormalize(mpfr_exp(l(), l(), MPFR_RNDD), MPFR_RNDD);
1734
+ u.subnormalize(mpfr_exp(u(), u(), MPFR_RNDU), MPFR_RNDU);
1735
+
1736
+ return representation(l.template get<T>(MPFR_RNDD), u.template get<T>(MPFR_RNDU));
1737
+ }
1738
+
1739
+ // exp ( bare interval ) mixed type
1740
+ template<typename T>
1741
+ template<typename T_>
1742
+ typename mpfr_bin_ieee754_flavor<T>::representation
1743
+ mpfr_bin_ieee754_flavor<T>::exp(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& x)
1744
+ {
1745
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1746
+
1747
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x))
1748
+ return empty();
1749
+
1750
+ // determine max. precision
1751
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
1752
+
1753
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
1754
+ // Error free for floating point inf-sup intervals due to outward rounding
1755
+ return convert_hull(
1756
+ mpfr_bin_ieee754_flavor<T_MAX>::exp(
1757
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
1758
+ )
1759
+ );
1760
+ }
1761
+
1762
+
1763
+ // exp ( decorated interval )
1764
+ template<typename T>
1765
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
1766
+ mpfr_bin_ieee754_flavor<T>::exp(mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
1767
+ {
1768
+ if (!is_valid(x) || is_nai(x))
1769
+ return nai();
1770
+
1771
+ // compute bare result
1772
+ representation bare = exp(x.first);
1773
+
1774
+ // compute decoration
1775
+ p1788::decoration::decoration dec = std::min(
1776
+ x.second,
1777
+ is_empty(bare) ? p1788::decoration::decoration::trv :
1778
+ is_common_interval(bare) ? p1788::decoration::decoration::com :
1779
+ p1788::decoration::decoration::dac);
1780
+ return representation_dec(bare, dec);
1781
+ }
1782
+
1783
+ // exp ( decorated interval ) mixed type
1784
+ template<typename T>
1785
+ template<typename T_>
1786
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
1787
+ mpfr_bin_ieee754_flavor<T>::exp(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& x)
1788
+ {
1789
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1790
+
1791
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x) || mpfr_bin_ieee754_flavor<T_>::is_nai(x))
1792
+ return nai();
1793
+
1794
+ // determine max. precision
1795
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
1796
+
1797
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
1798
+ // Error free for floating point inf-sup intervals due to outward rounding
1799
+ return convert_hull(
1800
+ mpfr_bin_ieee754_flavor<T_MAX>::exp(
1801
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
1802
+ )
1803
+ );
1804
+ }
1805
+
1806
+
1807
+ // exp2
1808
+
1809
+ // exp2 ( bare interval )
1810
+ template<typename T>
1811
+ typename mpfr_bin_ieee754_flavor<T>::representation
1812
+ mpfr_bin_ieee754_flavor<T>::exp2(mpfr_bin_ieee754_flavor<T>::representation const& x)
1813
+ {
1814
+ if (!is_valid(x) || is_empty(x))
1815
+ return empty();
1816
+
1817
+ mpfr_var::setup();
1818
+ mpfr_var l(x.first, MPFR_RNDD);
1819
+ mpfr_var u(x.second, MPFR_RNDU);
1820
+
1821
+ l.subnormalize(mpfr_exp2(l(), l(), MPFR_RNDD), MPFR_RNDD);
1822
+ u.subnormalize(mpfr_exp2(u(), u(), MPFR_RNDU), MPFR_RNDU);
1823
+
1824
+ return representation(l.template get<T>(MPFR_RNDD), u.template get<T>(MPFR_RNDU));
1825
+ }
1826
+
1827
+ // exp2 ( bare interval ) mixed type
1828
+ template<typename T>
1829
+ template<typename T_>
1830
+ typename mpfr_bin_ieee754_flavor<T>::representation
1831
+ mpfr_bin_ieee754_flavor<T>::exp2(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& x)
1832
+ {
1833
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1834
+
1835
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x))
1836
+ return empty();
1837
+
1838
+ // determine max. precision
1839
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
1840
+
1841
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
1842
+ // Error free for floating point inf-sup intervals due to outward rounding
1843
+ return convert_hull(
1844
+ mpfr_bin_ieee754_flavor<T_MAX>::exp2(
1845
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
1846
+ )
1847
+ );
1848
+ }
1849
+
1850
+
1851
+ // exp2 ( decorated interval )
1852
+ template<typename T>
1853
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
1854
+ mpfr_bin_ieee754_flavor<T>::exp2(mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
1855
+ {
1856
+ if (!is_valid(x) || is_nai(x))
1857
+ return nai();
1858
+
1859
+ // compute bare result
1860
+ representation bare = exp2(x.first);
1861
+
1862
+ // compute decoration
1863
+ p1788::decoration::decoration dec = std::min(
1864
+ x.second,
1865
+ is_empty(bare) ? p1788::decoration::decoration::trv :
1866
+ is_common_interval(bare) ? p1788::decoration::decoration::com :
1867
+ p1788::decoration::decoration::dac);
1868
+ return representation_dec(bare, dec);
1869
+ }
1870
+
1871
+ // exp2 ( decorated interval ) mixed type
1872
+ template<typename T>
1873
+ template<typename T_>
1874
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
1875
+ mpfr_bin_ieee754_flavor<T>::exp2(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& x)
1876
+ {
1877
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1878
+
1879
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x) || mpfr_bin_ieee754_flavor<T_>::is_nai(x))
1880
+ return nai();
1881
+
1882
+ // determine max. precision
1883
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
1884
+
1885
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
1886
+ // Error free for floating point inf-sup intervals due to outward rounding
1887
+ return convert_hull(
1888
+ mpfr_bin_ieee754_flavor<T_MAX>::exp2(
1889
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
1890
+ )
1891
+ );
1892
+ }
1893
+
1894
+
1895
+ // exp10
1896
+
1897
+ // exp10 ( bare interval )
1898
+ template<typename T>
1899
+ typename mpfr_bin_ieee754_flavor<T>::representation
1900
+ mpfr_bin_ieee754_flavor<T>::exp10(mpfr_bin_ieee754_flavor<T>::representation const& x)
1901
+ {
1902
+ if (!is_valid(x) || is_empty(x))
1903
+ return empty();
1904
+
1905
+ mpfr_var::setup();
1906
+ mpfr_var l(x.first, MPFR_RNDD);
1907
+ mpfr_var u(x.second, MPFR_RNDU);
1908
+
1909
+ l.subnormalize(mpfr_exp10(l(), l(), MPFR_RNDD), MPFR_RNDD);
1910
+ u.subnormalize(mpfr_exp10(u(), u(), MPFR_RNDU), MPFR_RNDU);
1911
+
1912
+ return representation(l.template get<T>(MPFR_RNDD), u.template get<T>(MPFR_RNDU));
1913
+ }
1914
+
1915
+ // exp10 ( bare interval ) mixed type
1916
+ template<typename T>
1917
+ template<typename T_>
1918
+ typename mpfr_bin_ieee754_flavor<T>::representation
1919
+ mpfr_bin_ieee754_flavor<T>::exp10(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& x)
1920
+ {
1921
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1922
+
1923
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x))
1924
+ return empty();
1925
+
1926
+ // determine max. precision
1927
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
1928
+
1929
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
1930
+ // Error free for floating point inf-sup intervals due to outward rounding
1931
+ return convert_hull(
1932
+ mpfr_bin_ieee754_flavor<T_MAX>::exp10(
1933
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
1934
+ )
1935
+ );
1936
+ }
1937
+
1938
+
1939
+ // exp10 ( decorated interval )
1940
+ template<typename T>
1941
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
1942
+ mpfr_bin_ieee754_flavor<T>::exp10(mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
1943
+ {
1944
+ if (!is_valid(x) || is_nai(x))
1945
+ return nai();
1946
+
1947
+ // compute bare result
1948
+ representation bare = exp10(x.first);
1949
+
1950
+ // compute decoration
1951
+ p1788::decoration::decoration dec = std::min(
1952
+ x.second,
1953
+ is_empty(bare) ? p1788::decoration::decoration::trv :
1954
+ is_common_interval(bare) ? p1788::decoration::decoration::com :
1955
+ p1788::decoration::decoration::dac);
1956
+ return representation_dec(bare, dec);
1957
+ }
1958
+
1959
+ // exp10 ( decorated interval ) mixed type
1960
+ template<typename T>
1961
+ template<typename T_>
1962
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
1963
+ mpfr_bin_ieee754_flavor<T>::exp10(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& x)
1964
+ {
1965
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1966
+
1967
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x) || mpfr_bin_ieee754_flavor<T_>::is_nai(x))
1968
+ return nai();
1969
+
1970
+ // determine max. precision
1971
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
1972
+
1973
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
1974
+ // Error free for floating point inf-sup intervals due to outward rounding
1975
+ return convert_hull(
1976
+ mpfr_bin_ieee754_flavor<T_MAX>::exp10(
1977
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
1978
+ )
1979
+ );
1980
+ }
1981
+
1982
+
1983
+
1984
+ // log
1985
+
1986
+ // log ( bare interval )
1987
+ template<typename T>
1988
+ typename mpfr_bin_ieee754_flavor<T>::representation
1989
+ mpfr_bin_ieee754_flavor<T>::log(mpfr_bin_ieee754_flavor<T>::representation const& x)
1990
+ {
1991
+ if (!is_valid(x))
1992
+ return empty();
1993
+
1994
+ representation xx = intersection(x, representation(0.0, std::numeric_limits<T>::infinity()));
1995
+
1996
+ if (is_empty(xx))
1997
+ return xx;
1998
+
1999
+ if (x.second <= 0.0)
2000
+ return empty();
2001
+
2002
+ mpfr_var::setup();
2003
+ mpfr_var xl(x.first <= 0.0 ? 0.0 : x.first, MPFR_RNDD);
2004
+ mpfr_var xu(x.second, MPFR_RNDU);
2005
+
2006
+ xl.subnormalize(mpfr_log(xl(), xl(), MPFR_RNDD), MPFR_RNDD);
2007
+ xu.subnormalize(mpfr_log(xu(), xu(), MPFR_RNDU), MPFR_RNDU);
2008
+
2009
+ return representation(xl.template get<T>(MPFR_RNDD), xu.template get<T>(MPFR_RNDU));
2010
+ }
2011
+
2012
+ // log ( bare interval ) mixed type
2013
+ template<typename T>
2014
+ template<typename T_>
2015
+ typename mpfr_bin_ieee754_flavor<T>::representation
2016
+ mpfr_bin_ieee754_flavor<T>::log(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& x)
2017
+ {
2018
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
2019
+
2020
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x))
2021
+ return empty();
2022
+
2023
+ // determine max. precision
2024
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
2025
+
2026
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
2027
+ // Error free for floating point inf-sup intervals due to outward rounding
2028
+ return convert_hull(
2029
+ mpfr_bin_ieee754_flavor<T_MAX>::log(
2030
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
2031
+ )
2032
+ );
2033
+ }
2034
+
2035
+
2036
+ // log ( decorated interval )
2037
+ template<typename T>
2038
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
2039
+ mpfr_bin_ieee754_flavor<T>::log(mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
2040
+ {
2041
+ if (!is_valid(x) || is_nai(x))
2042
+ return nai();
2043
+
2044
+ // compute bare result
2045
+ representation bare = log(x.first);
2046
+
2047
+ // compute decoration
2048
+ p1788::decoration::decoration dec = std::min(
2049
+ x.second,
2050
+ x.first.first <= 0.0 || is_empty(bare) ? p1788::decoration::decoration::trv :
2051
+ is_common_interval(bare) ? p1788::decoration::decoration::com :
2052
+ p1788::decoration::decoration::dac);
2053
+ return representation_dec(bare, dec);
2054
+ }
2055
+
2056
+ // log ( decorated interval ) mixed type
2057
+ template<typename T>
2058
+ template<typename T_>
2059
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
2060
+ mpfr_bin_ieee754_flavor<T>::log(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& x)
2061
+ {
2062
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
2063
+
2064
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x) || mpfr_bin_ieee754_flavor<T_>::is_nai(x))
2065
+ return nai();
2066
+
2067
+ // determine max. precision
2068
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
2069
+
2070
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
2071
+ // Error free for floating point inf-sup intervals due to outward rounding
2072
+ return convert_hull(
2073
+ mpfr_bin_ieee754_flavor<T_MAX>::log(
2074
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
2075
+ )
2076
+ );
2077
+ }
2078
+
2079
+
2080
+
2081
+ // log2
2082
+
2083
+ // log2 ( bare interval )
2084
+ template<typename T>
2085
+ typename mpfr_bin_ieee754_flavor<T>::representation
2086
+ mpfr_bin_ieee754_flavor<T>::log2(mpfr_bin_ieee754_flavor<T>::representation const& x)
2087
+ {
2088
+ if (!is_valid(x))
2089
+ return empty();
2090
+
2091
+ representation xx = intersection(x, representation(0.0, std::numeric_limits<T>::infinity()));
2092
+
2093
+ if (is_empty(xx))
2094
+ return xx;
2095
+
2096
+ if (x.second <= 0.0)
2097
+ return empty();
2098
+
2099
+ mpfr_var::setup();
2100
+ mpfr_var xl(x.first <= 0.0 ? 0.0 : x.first, MPFR_RNDD);
2101
+ mpfr_var xu(x.second, MPFR_RNDU);
2102
+
2103
+ xl.subnormalize(mpfr_log2(xl(), xl(), MPFR_RNDD), MPFR_RNDD);
2104
+ xu.subnormalize(mpfr_log2(xu(), xu(), MPFR_RNDU), MPFR_RNDU);
2105
+
2106
+ return representation(xl.template get<T>(MPFR_RNDD), xu.template get<T>(MPFR_RNDU));
2107
+ }
2108
+
2109
+ // log2 ( bare interval ) mixed type
2110
+ template<typename T>
2111
+ template<typename T_>
2112
+ typename mpfr_bin_ieee754_flavor<T>::representation
2113
+ mpfr_bin_ieee754_flavor<T>::log2(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& x)
2114
+ {
2115
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
2116
+
2117
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x))
2118
+ return empty();
2119
+
2120
+ // determine max. precision
2121
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
2122
+
2123
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
2124
+ // Error free for floating point inf-sup intervals due to outward rounding
2125
+ return convert_hull(
2126
+ mpfr_bin_ieee754_flavor<T_MAX>::log2(
2127
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
2128
+ )
2129
+ );
2130
+ }
2131
+
2132
+
2133
+ // log2 ( decorated interval )
2134
+ template<typename T>
2135
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
2136
+ mpfr_bin_ieee754_flavor<T>::log2(mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
2137
+ {
2138
+ if (!is_valid(x) || is_nai(x))
2139
+ return nai();
2140
+
2141
+ // compute bare result
2142
+ representation bare = log2(x.first);
2143
+
2144
+ // compute decoration
2145
+ p1788::decoration::decoration dec = std::min(
2146
+ x.second,
2147
+ x.first.first <= 0.0 || is_empty(bare) ? p1788::decoration::decoration::trv :
2148
+ is_common_interval(bare) ? p1788::decoration::decoration::com :
2149
+ p1788::decoration::decoration::dac);
2150
+ return representation_dec(bare, dec);
2151
+ }
2152
+
2153
+ // log2 ( decorated interval ) mixed type
2154
+ template<typename T>
2155
+ template<typename T_>
2156
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
2157
+ mpfr_bin_ieee754_flavor<T>::log2(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& x)
2158
+ {
2159
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
2160
+
2161
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x) || mpfr_bin_ieee754_flavor<T_>::is_nai(x))
2162
+ return nai();
2163
+
2164
+ // determine max. precision
2165
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
2166
+
2167
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
2168
+ // Error free for floating point inf-sup intervals due to outward rounding
2169
+ return convert_hull(
2170
+ mpfr_bin_ieee754_flavor<T_MAX>::log2(
2171
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
2172
+ )
2173
+ );
2174
+ }
2175
+
2176
+
2177
+ // log10
2178
+
2179
+ // log10 ( bare interval )
2180
+ template<typename T>
2181
+ typename mpfr_bin_ieee754_flavor<T>::representation
2182
+ mpfr_bin_ieee754_flavor<T>::log10(mpfr_bin_ieee754_flavor<T>::representation const& x)
2183
+ {
2184
+ if (!is_valid(x))
2185
+ return empty();
2186
+
2187
+ representation xx = intersection(x, representation(0.0, std::numeric_limits<T>::infinity()));
2188
+
2189
+ if (is_empty(xx))
2190
+ return xx;
2191
+
2192
+ if (x.second <= 0.0)
2193
+ return empty();
2194
+
2195
+ mpfr_var::setup();
2196
+ mpfr_var xl(x.first <= 0.0 ? 0.0 : x.first, MPFR_RNDD);
2197
+ mpfr_var xu(x.second, MPFR_RNDU);
2198
+
2199
+ xl.subnormalize(mpfr_log10(xl(), xl(), MPFR_RNDD), MPFR_RNDD);
2200
+ xu.subnormalize(mpfr_log10(xu(), xu(), MPFR_RNDU), MPFR_RNDU);
2201
+
2202
+ return representation(xl.template get<T>(MPFR_RNDD), xu.template get<T>(MPFR_RNDU));
2203
+ }
2204
+
2205
+ // log10 ( bare interval ) mixed type
2206
+ template<typename T>
2207
+ template<typename T_>
2208
+ typename mpfr_bin_ieee754_flavor<T>::representation
2209
+ mpfr_bin_ieee754_flavor<T>::log10(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& x)
2210
+ {
2211
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
2212
+
2213
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x))
2214
+ return empty();
2215
+
2216
+ // determine max. precision
2217
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
2218
+
2219
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
2220
+ // Error free for floating point inf-sup intervals due to outward rounding
2221
+ return convert_hull(
2222
+ mpfr_bin_ieee754_flavor<T_MAX>::log10(
2223
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
2224
+ )
2225
+ );
2226
+ }
2227
+
2228
+
2229
+ // log10 ( decorated interval )
2230
+ template<typename T>
2231
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
2232
+ mpfr_bin_ieee754_flavor<T>::log10(mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
2233
+ {
2234
+ if (!is_valid(x) || is_nai(x))
2235
+ return nai();
2236
+
2237
+ // compute bare result
2238
+ representation bare = log10(x.first);
2239
+
2240
+ // compute decoration
2241
+ p1788::decoration::decoration dec = std::min(
2242
+ x.second,
2243
+ x.first.first <= 0.0 || is_empty(bare) ? p1788::decoration::decoration::trv :
2244
+ is_common_interval(bare) ? p1788::decoration::decoration::com :
2245
+ p1788::decoration::decoration::dac);
2246
+ return representation_dec(bare, dec);
2247
+ }
2248
+
2249
+ // log10 ( decorated interval ) mixed type
2250
+ template<typename T>
2251
+ template<typename T_>
2252
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
2253
+ mpfr_bin_ieee754_flavor<T>::log10(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& x)
2254
+ {
2255
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
2256
+
2257
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x) || mpfr_bin_ieee754_flavor<T_>::is_nai(x))
2258
+ return nai();
2259
+
2260
+ // determine max. precision
2261
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
2262
+
2263
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
2264
+ // Error free for floating point inf-sup intervals due to outward rounding
2265
+ return convert_hull(
2266
+ mpfr_bin_ieee754_flavor<T_MAX>::log10(
2267
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
2268
+ )
2269
+ );
2270
+ }
2271
+
2272
+
2273
+ // sin
2274
+
2275
+ // sin ( bare interval )
2276
+ template<typename T>
2277
+ typename mpfr_bin_ieee754_flavor<T>::representation
2278
+ mpfr_bin_ieee754_flavor<T>::sin(mpfr_bin_ieee754_flavor<T>::representation const& x)
2279
+ {
2280
+ //TODO ueberarbeiten? die Null-Faelle zusammenfassen. Cos dann natuerlich auch
2281
+
2282
+ if (!is_valid(x) || is_empty(x))
2283
+ return empty();
2284
+
2285
+ mpfr_var::setup();
2286
+
2287
+ mpfr_var xl(x.first, MPFR_RNDD);
2288
+ mpfr_var xu(x.second, MPFR_RNDU);
2289
+
2290
+ // pi
2291
+ // mpfr_var pi(-1.0, MPFR_RNDD);
2292
+ // mpfr_acos(pi(), pi(), MPFR_RNDD);
2293
+ mpfr_var pi;
2294
+ mpfr_const_pi(pi(), MPFR_RNDD);
2295
+
2296
+
2297
+ mpfr_var w;
2298
+ mpfr_sub(w(), xu(), xl(), MPFR_RNDU);
2299
+
2300
+ mpfr_var tmp;
2301
+
2302
+ // cos(lower)
2303
+ tmp.subnormalize(mpfr_cos(tmp(), xl(), MPFR_RNDD), MPFR_RNDD);
2304
+ int df_lower = mpfr_sgn(tmp());
2305
+
2306
+ // cos(upper)
2307
+ tmp.subnormalize(mpfr_cos(tmp(), xu(), MPFR_RNDU), MPFR_RNDU);
2308
+ int df_upper = mpfr_sgn(tmp());
2309
+
2310
+ if (df_lower != df_upper)
2311
+ {
2312
+ if (df_lower == 0)
2313
+ {
2314
+ if (mpfr_cmp(w(), pi()) > 0)
2315
+ return representation(-1.0, 1.0);
2316
+ }
2317
+ else if (df_upper == 0)
2318
+ {
2319
+ if (mpfr_cmp(w(), pi()) > 0)
2320
+ return representation(-1.0, 1.0);
2321
+ }
2322
+ else
2323
+ {
2324
+ mpfr_var pi2;
2325
+ mpfr_mul_si(pi2(), pi(), 2, MPFR_RNDD);
2326
+
2327
+ if (mpfr_cmp(w(), pi2()) > 0)
2328
+ return representation(-1.0, 1.0);
2329
+
2330
+ if (df_lower > 0)
2331
+ {
2332
+ mpfr_var l1;
2333
+ mpfr_var l2;
2334
+ l1.subnormalize(mpfr_sin(l1(), xl(), MPFR_RNDD), MPFR_RNDD);
2335
+ l2.subnormalize(mpfr_sin(l2(), xu(), MPFR_RNDD), MPFR_RNDD);
2336
+
2337
+ return representation(std::min(l1.template get<T>(MPFR_RNDD), l2.template get<T>(MPFR_RNDD)), 1.0);
2338
+ }
2339
+
2340
+ mpfr_var u1;
2341
+ mpfr_var u2;
2342
+ u1.subnormalize(mpfr_sin(u1(), xl(), MPFR_RNDU), MPFR_RNDU);
2343
+ u2.subnormalize(mpfr_sin(u2(), xu(), MPFR_RNDU), MPFR_RNDU);
2344
+
2345
+ return representation(-1.0, std::max(u1.template get<T>(MPFR_RNDU), u2.template get<T>(MPFR_RNDU)));
2346
+ }
2347
+ }
2348
+ else if (mpfr_cmp(w(), pi()) > 0)
2349
+ return representation(-1.0, 1.0);
2350
+
2351
+ mpfr_var l1;
2352
+ mpfr_var l2;
2353
+ l1.subnormalize(mpfr_sin(l1(), xl(), MPFR_RNDD), MPFR_RNDD);
2354
+ l2.subnormalize(mpfr_sin(l2(), xu(), MPFR_RNDD), MPFR_RNDD);
2355
+
2356
+ mpfr_var u1;
2357
+ mpfr_var u2;
2358
+ u1.subnormalize(mpfr_sin(u1(), xl(), MPFR_RNDU), MPFR_RNDU);
2359
+ u2.subnormalize(mpfr_sin(u2(), xu(), MPFR_RNDU), MPFR_RNDU);
2360
+
2361
+ return representation(std::min(l1.template get<T>(MPFR_RNDD), l2.template get<T>(MPFR_RNDD)),
2362
+ std::max(u1.template get<T>(MPFR_RNDU), u2.template get<T>(MPFR_RNDU)));
2363
+ }
2364
+
2365
+ // sin ( bare interval ) mixed type
2366
+ template<typename T>
2367
+ template<typename T_>
2368
+ typename mpfr_bin_ieee754_flavor<T>::representation
2369
+ mpfr_bin_ieee754_flavor<T>::sin(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& x)
2370
+ {
2371
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
2372
+
2373
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x))
2374
+ return empty();
2375
+
2376
+ // determine max. precision
2377
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
2378
+
2379
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
2380
+ // Error free for floating point inf-sup intervals due to outward rounding
2381
+ return convert_hull(
2382
+ mpfr_bin_ieee754_flavor<T_MAX>::sin(
2383
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
2384
+ )
2385
+ );
2386
+ }
2387
+
2388
+
2389
+ // sin ( decorated interval )
2390
+ template<typename T>
2391
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
2392
+ mpfr_bin_ieee754_flavor<T>::sin(mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
2393
+ {
2394
+ if (!is_valid(x) || is_nai(x))
2395
+ return nai();
2396
+
2397
+ // compute bare result
2398
+ representation bare = sin(x.first);
2399
+
2400
+ // compute decoration
2401
+ p1788::decoration::decoration dec = std::min(
2402
+ x.second,
2403
+ is_empty(bare) ? p1788::decoration::decoration::trv :
2404
+ is_common_interval(bare) ? p1788::decoration::decoration::com :
2405
+ p1788::decoration::decoration::dac);
2406
+ return representation_dec(bare, dec);
2407
+ }
2408
+
2409
+ // sin ( decorated interval ) mixed type
2410
+ template<typename T>
2411
+ template<typename T_>
2412
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
2413
+ mpfr_bin_ieee754_flavor<T>::sin(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& x)
2414
+ {
2415
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
2416
+
2417
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x) || mpfr_bin_ieee754_flavor<T_>::is_nai(x))
2418
+ return nai();
2419
+
2420
+ // determine max. precision
2421
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
2422
+
2423
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
2424
+ // Error free for floating point inf-sup intervals due to outward rounding
2425
+ return convert_hull(
2426
+ mpfr_bin_ieee754_flavor<T_MAX>::sin(
2427
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
2428
+ )
2429
+ );
2430
+ }
2431
+
2432
+
2433
+ // cos
2434
+
2435
+ // cos ( bare interval )
2436
+ template<typename T>
2437
+ typename mpfr_bin_ieee754_flavor<T>::representation
2438
+ mpfr_bin_ieee754_flavor<T>::cos(mpfr_bin_ieee754_flavor<T>::representation const& x)
2439
+ {
2440
+ if (!is_valid(x) || is_empty(x))
2441
+ return empty();
2442
+
2443
+ mpfr_var::setup();
2444
+
2445
+ mpfr_var xl(x.first, MPFR_RNDD);
2446
+ mpfr_var xu(x.second, MPFR_RNDU);
2447
+
2448
+ // pi
2449
+ // mpfr_var pi(-1.0, MPFR_RNDD);
2450
+ // mpfr_acos(pi(), pi(), MPFR_RNDD);
2451
+ mpfr_var pi;
2452
+ mpfr_const_pi(pi(), MPFR_RNDD);
2453
+
2454
+ mpfr_var w;
2455
+ mpfr_sub(w(), xu(), xl(), MPFR_RNDU);
2456
+
2457
+ mpfr_var tmp;
2458
+
2459
+ // -sin(lower)
2460
+ tmp.subnormalize(mpfr_sin(tmp(), xl(), MPFR_RNDD), MPFR_RNDD);
2461
+ mpfr_neg(tmp(), tmp(), MPFR_RNDD);
2462
+ int df_lower = mpfr_sgn(tmp());
2463
+
2464
+ // -sin(upper)
2465
+ tmp.subnormalize(mpfr_sin(tmp(), xu(), MPFR_RNDU), MPFR_RNDU);
2466
+ mpfr_neg(tmp(), tmp(), MPFR_RNDU);
2467
+ int df_upper = mpfr_sgn(tmp());
2468
+
2469
+ if (df_lower != df_upper)
2470
+ {
2471
+ if (df_lower == 0)
2472
+ {
2473
+ if (mpfr_cmp(w(), pi()) > 0)
2474
+ return representation(-1.0, 1.0);
2475
+ }
2476
+ else if (df_upper == 0)
2477
+ {
2478
+ if (mpfr_cmp(w(), pi()) > 0)
2479
+ return representation(-1.0, 1.0);
2480
+ }
2481
+ else
2482
+ {
2483
+ mpfr_var pi2;
2484
+ mpfr_mul_si(pi2(), pi(), 2, MPFR_RNDD);
2485
+
2486
+ if (mpfr_cmp(w(), pi2()) > 0)
2487
+ return representation(-1.0, 1.0);
2488
+
2489
+ if (df_lower > 0)
2490
+ {
2491
+ mpfr_var l1;
2492
+ mpfr_var l2;
2493
+ l1.subnormalize(mpfr_cos(l1(), xl(), MPFR_RNDD), MPFR_RNDD);
2494
+ l2.subnormalize(mpfr_cos(l2(), xu(), MPFR_RNDD), MPFR_RNDD);
2495
+
2496
+ return representation(std::min(l1.template get<T>(MPFR_RNDD), l2.template get<T>(MPFR_RNDD)), 1.0);
2497
+ }
2498
+
2499
+ mpfr_var u1;
2500
+ mpfr_var u2;
2501
+ u1.subnormalize(mpfr_cos(u1(), xl(), MPFR_RNDU), MPFR_RNDU);
2502
+ u2.subnormalize(mpfr_cos(u2(), xu(), MPFR_RNDU), MPFR_RNDU);
2503
+
2504
+ return representation(-1.0, std::max(u1.template get<T>(MPFR_RNDU), u2.template get<T>(MPFR_RNDU)));
2505
+ }
2506
+ }
2507
+ else if (mpfr_cmp(w(), pi()) > 0)
2508
+ return representation(-1.0, 1.0);
2509
+
2510
+ mpfr_var l1;
2511
+ mpfr_var l2;
2512
+ l1.subnormalize(mpfr_cos(l1(), xl(), MPFR_RNDD), MPFR_RNDD);
2513
+ l2.subnormalize(mpfr_cos(l2(), xu(), MPFR_RNDD), MPFR_RNDD);
2514
+
2515
+ mpfr_var u1;
2516
+ mpfr_var u2;
2517
+ u1.subnormalize(mpfr_cos(u1(), xl(), MPFR_RNDU), MPFR_RNDU);
2518
+ u2.subnormalize(mpfr_cos(u2(), xu(), MPFR_RNDU), MPFR_RNDU);
2519
+
2520
+ return representation(std::min(l1.template get<T>(MPFR_RNDD), l2.template get<T>(MPFR_RNDD)),
2521
+ std::max(u1.template get<T>(MPFR_RNDU), u2.template get<T>(MPFR_RNDU)));
2522
+ }
2523
+
2524
+ // cos ( bare interval ) mixed type
2525
+ template<typename T>
2526
+ template<typename T_>
2527
+ typename mpfr_bin_ieee754_flavor<T>::representation
2528
+ mpfr_bin_ieee754_flavor<T>::cos(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& x)
2529
+ {
2530
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
2531
+
2532
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x))
2533
+ return empty();
2534
+
2535
+ // determine max. precision
2536
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
2537
+
2538
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
2539
+ // Error free for floating point inf-sup intervals due to outward rounding
2540
+ return convert_hull(
2541
+ mpfr_bin_ieee754_flavor<T_MAX>::cos(
2542
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
2543
+ )
2544
+ );
2545
+ }
2546
+
2547
+
2548
+ // cos ( decorated interval )
2549
+ template<typename T>
2550
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
2551
+ mpfr_bin_ieee754_flavor<T>::cos(mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
2552
+ {
2553
+ if (!is_valid(x) || is_nai(x))
2554
+ return nai();
2555
+
2556
+ // compute bare result
2557
+ representation bare = cos(x.first);
2558
+
2559
+ // compute decoration
2560
+ p1788::decoration::decoration dec = std::min(
2561
+ x.second,
2562
+ is_empty(bare) ? p1788::decoration::decoration::trv :
2563
+ is_common_interval(bare) ? p1788::decoration::decoration::com :
2564
+ p1788::decoration::decoration::dac);
2565
+ return representation_dec(bare, dec);
2566
+ }
2567
+
2568
+ // cos ( decorated interval ) mixed type
2569
+ template<typename T>
2570
+ template<typename T_>
2571
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
2572
+ mpfr_bin_ieee754_flavor<T>::cos(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& x)
2573
+ {
2574
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
2575
+
2576
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x) || mpfr_bin_ieee754_flavor<T_>::is_nai(x))
2577
+ return nai();
2578
+
2579
+ // determine max. precision
2580
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
2581
+
2582
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
2583
+ // Error free for floating point inf-sup intervals due to outward rounding
2584
+ return convert_hull(
2585
+ mpfr_bin_ieee754_flavor<T_MAX>::cos(
2586
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
2587
+ )
2588
+ );
2589
+ }
2590
+
2591
+
2592
+ // tan
2593
+
2594
+ // tan ( bare interval )
2595
+ template<typename T>
2596
+ typename mpfr_bin_ieee754_flavor<T>::representation
2597
+ mpfr_bin_ieee754_flavor<T>::tan(mpfr_bin_ieee754_flavor<T>::representation const& x)
2598
+ {
2599
+ if (!is_valid(x) || is_empty(x))
2600
+ return empty();
2601
+
2602
+ mpfr_var::setup();
2603
+
2604
+ mpfr_var xl(x.first, MPFR_RNDD);
2605
+ mpfr_var xu(x.second, MPFR_RNDU);
2606
+
2607
+ mpfr_var pi;
2608
+ mpfr_const_pi(pi(), MPFR_RNDD);
2609
+
2610
+ mpfr_var w;
2611
+ mpfr_sub(w(), xu(), xl(), MPFR_RNDU);
2612
+
2613
+ if (mpfr_cmp(w(), pi()) > 0)
2614
+ return entire();
2615
+
2616
+ xl.subnormalize(mpfr_tan(xl(), xl(), MPFR_RNDD), MPFR_RNDD);
2617
+ xu.subnormalize(mpfr_tan(xu(), xu(), MPFR_RNDU), MPFR_RNDU);
2618
+
2619
+ if (mpfr_cmp(xl(), xu()) > 0)
2620
+ return entire();
2621
+
2622
+ return representation(xl.template get<T>(MPFR_RNDD), xu.template get<T>(MPFR_RNDU));
2623
+ }
2624
+
2625
+
2626
+ // tan ( bare interval ) mixed type
2627
+ template<typename T>
2628
+ template<typename T_>
2629
+ typename mpfr_bin_ieee754_flavor<T>::representation
2630
+ mpfr_bin_ieee754_flavor<T>::tan(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& x)
2631
+ {
2632
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
2633
+
2634
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x))
2635
+ return empty();
2636
+
2637
+ // determine max. precision
2638
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
2639
+
2640
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
2641
+ // Error free for floating point inf-sup intervals due to outward rounding
2642
+ return convert_hull(
2643
+ mpfr_bin_ieee754_flavor<T_MAX>::tan(
2644
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
2645
+ )
2646
+ );
2647
+ }
2648
+
2649
+
2650
+ // tan ( decorated interval )
2651
+ template<typename T>
2652
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
2653
+ mpfr_bin_ieee754_flavor<T>::tan(mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
2654
+ {
2655
+ if (!is_valid(x) || is_nai(x))
2656
+ return nai();
2657
+
2658
+ if (is_empty(x))
2659
+ return empty_dec();
2660
+
2661
+ mpfr_var::setup();
2662
+
2663
+ mpfr_var xl(x.first.first, MPFR_RNDD);
2664
+ mpfr_var xu(x.first.second, MPFR_RNDU);
2665
+
2666
+ mpfr_var pi;
2667
+ mpfr_const_pi(pi(), MPFR_RNDD);
2668
+
2669
+ mpfr_var w;
2670
+ mpfr_sub(w(), xu(), xl(), MPFR_RNDU);
2671
+
2672
+ if (mpfr_cmp(w(), pi()) > 0)
2673
+ return representation_dec(entire(), p1788::decoration::decoration::trv);
2674
+
2675
+ xl.subnormalize(mpfr_tan(xl(), xl(), MPFR_RNDD), MPFR_RNDD);
2676
+ xu.subnormalize(mpfr_tan(xu(), xu(), MPFR_RNDU), MPFR_RNDU);
2677
+
2678
+ if (mpfr_cmp(xl(), xu()) > 0)
2679
+ return representation_dec(entire(), p1788::decoration::decoration::trv);
2680
+
2681
+ representation bare(xl.template get<T>(MPFR_RNDD), xu.template get<T>(MPFR_RNDU));
2682
+ p1788::decoration::decoration dec = std::min(x.second,
2683
+ is_common_interval(bare) ? p1788::decoration::decoration::com :
2684
+ p1788::decoration::decoration::dac);
2685
+
2686
+ return representation_dec(bare, dec);
2687
+ }
2688
+
2689
+ // tan ( decorated interval ) mixed type
2690
+ template<typename T>
2691
+ template<typename T_>
2692
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
2693
+ mpfr_bin_ieee754_flavor<T>::tan(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& x)
2694
+ {
2695
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
2696
+
2697
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x) || mpfr_bin_ieee754_flavor<T_>::is_nai(x))
2698
+ return nai();
2699
+
2700
+ // determine max. precision
2701
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
2702
+
2703
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
2704
+ // Error free for floating point inf-sup intervals due to outward rounding
2705
+ return convert_hull(
2706
+ mpfr_bin_ieee754_flavor<T_MAX>::tan(
2707
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
2708
+ )
2709
+ );
2710
+ }
2711
+
2712
+
2713
+ // asin
2714
+
2715
+ // asin ( bare interval )
2716
+ template<typename T>
2717
+ typename mpfr_bin_ieee754_flavor<T>::representation
2718
+ mpfr_bin_ieee754_flavor<T>::asin(mpfr_bin_ieee754_flavor<T>::representation const& x)
2719
+ {
2720
+ if (!is_valid(x))
2721
+ return empty();
2722
+
2723
+ representation xx = intersection(x, representation(-1.0, 1.0));
2724
+
2725
+ if (is_empty(xx))
2726
+ return xx;
2727
+
2728
+ mpfr_var::setup();
2729
+
2730
+ mpfr_var xl(xx.first, MPFR_RNDD);
2731
+ mpfr_var xu(xx.second, MPFR_RNDU);
2732
+
2733
+ xl.subnormalize(mpfr_asin(xl(), xl(), MPFR_RNDD), MPFR_RNDD);
2734
+ xu.subnormalize(mpfr_asin(xu(), xu(), MPFR_RNDU), MPFR_RNDU);
2735
+
2736
+ return representation(xl.template get<T>(MPFR_RNDD), xu.template get<T>(MPFR_RNDU));
2737
+ }
2738
+
2739
+ // asin ( bare interval ) mixed type
2740
+ template<typename T>
2741
+ template<typename T_>
2742
+ typename mpfr_bin_ieee754_flavor<T>::representation
2743
+ mpfr_bin_ieee754_flavor<T>::asin(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& x)
2744
+ {
2745
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
2746
+
2747
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x))
2748
+ return empty();
2749
+
2750
+ // determine max. precision
2751
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
2752
+
2753
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
2754
+ // Error free for floating point inf-sup intervals due to outward rounding
2755
+ return convert_hull(
2756
+ mpfr_bin_ieee754_flavor<T_MAX>::asin(
2757
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
2758
+ )
2759
+ );
2760
+ }
2761
+
2762
+
2763
+ // asin ( decorated interval )
2764
+ template<typename T>
2765
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
2766
+ mpfr_bin_ieee754_flavor<T>::asin(mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
2767
+ {
2768
+ if (!is_valid(x) || is_nai(x))
2769
+ return nai();
2770
+
2771
+ // compute bare result
2772
+ representation bare = asin(x.first);
2773
+
2774
+ // compute decoration
2775
+ p1788::decoration::decoration dec = std::min(
2776
+ x.second,
2777
+ x.first.first < -1.0 || x.first.second > 1.0 || is_empty(bare) ? p1788::decoration::decoration::trv
2778
+ : p1788::decoration::decoration::com);
2779
+
2780
+ return representation_dec(bare, dec);
2781
+ }
2782
+
2783
+ // asin ( decorated interval ) mixed type
2784
+ template<typename T>
2785
+ template<typename T_>
2786
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
2787
+ mpfr_bin_ieee754_flavor<T>::asin(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& x)
2788
+ {
2789
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
2790
+
2791
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x) || mpfr_bin_ieee754_flavor<T_>::is_nai(x))
2792
+ return nai();
2793
+
2794
+ // determine max. precision
2795
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
2796
+
2797
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
2798
+ // Error free for floating point inf-sup intervals due to outward rounding
2799
+ return convert_hull(
2800
+ mpfr_bin_ieee754_flavor<T_MAX>::asin(
2801
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
2802
+ )
2803
+ );
2804
+ }
2805
+
2806
+
2807
+ // acos
2808
+
2809
+ // acos ( bare interval )
2810
+ template<typename T>
2811
+ typename mpfr_bin_ieee754_flavor<T>::representation
2812
+ mpfr_bin_ieee754_flavor<T>::acos(mpfr_bin_ieee754_flavor<T>::representation const& x)
2813
+ {
2814
+ if (!is_valid(x))
2815
+ return empty();
2816
+
2817
+ representation xx = intersection(x, representation(-1.0, 1.0));
2818
+
2819
+ if (is_empty(xx))
2820
+ return xx;
2821
+
2822
+ mpfr_var::setup();
2823
+
2824
+ mpfr_var xl(xx.first, MPFR_RNDD);
2825
+ mpfr_var xu(xx.second, MPFR_RNDU);
2826
+
2827
+ xu.subnormalize(mpfr_acos(xu(), xu(), MPFR_RNDD), MPFR_RNDD);
2828
+ xl.subnormalize(mpfr_acos(xl(), xl(), MPFR_RNDU), MPFR_RNDU);
2829
+
2830
+ return representation(xu.template get<T>(MPFR_RNDD), xl.template get<T>(MPFR_RNDU));
2831
+ }
2832
+
2833
+
2834
+ // acos ( bare interval ) mixed type
2835
+ template<typename T>
2836
+ template<typename T_>
2837
+ typename mpfr_bin_ieee754_flavor<T>::representation
2838
+ mpfr_bin_ieee754_flavor<T>::acos(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& x)
2839
+ {
2840
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
2841
+
2842
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x))
2843
+ return empty();
2844
+
2845
+ // determine max. precision
2846
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
2847
+
2848
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
2849
+ // Error free for floating point inf-sup intervals due to outward rounding
2850
+ return convert_hull(
2851
+ mpfr_bin_ieee754_flavor<T_MAX>::acos(
2852
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
2853
+ )
2854
+ );
2855
+ }
2856
+
2857
+
2858
+ // acos ( decorated interval )
2859
+ template<typename T>
2860
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
2861
+ mpfr_bin_ieee754_flavor<T>::acos(mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
2862
+ {
2863
+ if (!is_valid(x) || is_nai(x))
2864
+ return nai();
2865
+
2866
+ // compute bare result
2867
+ representation bare = acos(x.first);
2868
+
2869
+ // compute decoration
2870
+ p1788::decoration::decoration dec = std::min(
2871
+ x.second,
2872
+ x.first.first < -1.0 || x.first.second > 1.0 || is_empty(bare) ? p1788::decoration::decoration::trv
2873
+ : p1788::decoration::decoration::com);
2874
+
2875
+ return representation_dec(bare, dec);
2876
+ }
2877
+
2878
+ // acos ( decorated interval ) mixed type
2879
+ template<typename T>
2880
+ template<typename T_>
2881
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
2882
+ mpfr_bin_ieee754_flavor<T>::acos(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& x)
2883
+ {
2884
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
2885
+
2886
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x) || mpfr_bin_ieee754_flavor<T_>::is_nai(x))
2887
+ return nai();
2888
+
2889
+ // determine max. precision
2890
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
2891
+
2892
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
2893
+ // Error free for floating point inf-sup intervals due to outward rounding
2894
+ return convert_hull(
2895
+ mpfr_bin_ieee754_flavor<T_MAX>::acos(
2896
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
2897
+ )
2898
+ );
2899
+ }
2900
+
2901
+
2902
+ // atan
2903
+
2904
+ // atan ( bare interval )
2905
+ template<typename T>
2906
+ typename mpfr_bin_ieee754_flavor<T>::representation
2907
+ mpfr_bin_ieee754_flavor<T>::atan(mpfr_bin_ieee754_flavor<T>::representation const& x)
2908
+ {
2909
+ if (!is_valid(x) || is_empty(x))
2910
+ return empty();
2911
+
2912
+ mpfr_var::setup();
2913
+
2914
+ mpfr_var xl(x.first, MPFR_RNDD);
2915
+ mpfr_var xu(x.second, MPFR_RNDU);
2916
+
2917
+ xl.subnormalize(mpfr_atan(xl(), xl(), MPFR_RNDD), MPFR_RNDD);
2918
+ xu.subnormalize(mpfr_atan(xu(), xu(), MPFR_RNDU), MPFR_RNDU);
2919
+
2920
+ return representation(xl.template get<T>(MPFR_RNDD), xu.template get<T>(MPFR_RNDU));
2921
+ }
2922
+
2923
+
2924
+ // atan ( bare interval ) mixed type
2925
+ template<typename T>
2926
+ template<typename T_>
2927
+ typename mpfr_bin_ieee754_flavor<T>::representation
2928
+ mpfr_bin_ieee754_flavor<T>::atan(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& x)
2929
+ {
2930
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
2931
+
2932
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x))
2933
+ return empty();
2934
+
2935
+ // determine max. precision
2936
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
2937
+
2938
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
2939
+ // Error free for floating point inf-sup intervals due to outward rounding
2940
+ return convert_hull(
2941
+ mpfr_bin_ieee754_flavor<T_MAX>::atan(
2942
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
2943
+ )
2944
+ );
2945
+ }
2946
+
2947
+
2948
+ // atan ( decorated interval )
2949
+ template<typename T>
2950
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
2951
+ mpfr_bin_ieee754_flavor<T>::atan(mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
2952
+ {
2953
+ if (!is_valid(x) || is_nai(x))
2954
+ return nai();
2955
+
2956
+ // compute bare result
2957
+ representation bare = atan(x.first);
2958
+
2959
+ // compute decoration
2960
+ p1788::decoration::decoration dec = std::min(
2961
+ x.second,
2962
+ is_empty(bare) ? p1788::decoration::decoration::trv : p1788::decoration::decoration::com);
2963
+
2964
+ return representation_dec(bare, dec);
2965
+ }
2966
+
2967
+ // atan ( decorated interval ) mixed type
2968
+ template<typename T>
2969
+ template<typename T_>
2970
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
2971
+ mpfr_bin_ieee754_flavor<T>::atan(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& x)
2972
+ {
2973
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
2974
+
2975
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x) || mpfr_bin_ieee754_flavor<T_>::is_nai(x))
2976
+ return nai();
2977
+
2978
+ // determine max. precision
2979
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
2980
+
2981
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
2982
+ // Error free for floating point inf-sup intervals due to outward rounding
2983
+ return convert_hull(
2984
+ mpfr_bin_ieee754_flavor<T_MAX>::atan(
2985
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
2986
+ )
2987
+ );
2988
+ }
2989
+
2990
+
2991
+
2992
+ // atan2
2993
+
2994
+ // atan2 ( bare interval )
2995
+ template<typename T>
2996
+ typename mpfr_bin_ieee754_flavor<T>::representation
2997
+ mpfr_bin_ieee754_flavor<T>::atan2(mpfr_bin_ieee754_flavor<T>::representation const& y,
2998
+ mpfr_bin_ieee754_flavor<T>::representation const& x)
2999
+ {
3000
+ if (!is_valid(y) || !is_valid(x) || is_empty(y) || is_empty(x) ||
3001
+ (y.first == 0.0 && y.second == 0.0 && x.first == 0.0 && x.second == 0.0))
3002
+ return empty();
3003
+
3004
+ mpfr_var::setup();
3005
+
3006
+ mpfr_var l;
3007
+ mpfr_var u;
3008
+
3009
+ mpfr_var yl(y.first, MPFR_RNDD);
3010
+ mpfr_var yu(y.second, MPFR_RNDU);
3011
+ mpfr_var xl(x.first, MPFR_RNDD);
3012
+ mpfr_var xu(x.second, MPFR_RNDU);
3013
+
3014
+ if (y.first >= 0.0 && y.second > 0.0)
3015
+ {
3016
+ if (x.first == 0.0 && x.second == 0.0)
3017
+ {
3018
+ l.subnormalize(mpfr_atan2(l(), yu(), xl(), MPFR_RNDD), MPFR_RNDD); // pi/2
3019
+ u.subnormalize(mpfr_atan2(u(), yu(), xl(), MPFR_RNDU), MPFR_RNDU); // pi/2
3020
+ }
3021
+ else if (x.first >= 0.0)
3022
+ {
3023
+ l.subnormalize(mpfr_atan2(l(), yl(), xu(), MPFR_RNDD), MPFR_RNDD);
3024
+ u.subnormalize(mpfr_atan2(u(), yu(), xl(), MPFR_RNDU), MPFR_RNDU);
3025
+ }
3026
+ else if (x.second <= 0.0)
3027
+ {
3028
+ l.subnormalize(mpfr_atan2(l(), yu(), xu(), MPFR_RNDD), MPFR_RNDD);
3029
+
3030
+ if (y.first == 0.0)
3031
+ u.subnormalize(mpfr_const_pi(u(), MPFR_RNDU), MPFR_RNDU); // pi
3032
+ else
3033
+ u.subnormalize(mpfr_atan2(u(), yl(), xl(), MPFR_RNDU), MPFR_RNDU);
3034
+ }
3035
+ else
3036
+ {
3037
+ if (y.first == 0.0)
3038
+ {
3039
+ l.set(0.0, MPFR_RNDD);
3040
+ u.subnormalize(mpfr_const_pi(u(), MPFR_RNDU), MPFR_RNDU); // pi
3041
+ }
3042
+ else
3043
+ {
3044
+ l.subnormalize(mpfr_atan2(l(), yl(), xu(), MPFR_RNDD), MPFR_RNDD);
3045
+ u.subnormalize(mpfr_atan2(u(), yl(), xl(), MPFR_RNDU), MPFR_RNDU);
3046
+ }
3047
+ }
3048
+ }
3049
+ else if (y.first < 0.0 && y.second <= 0.0)
3050
+ {
3051
+ if (x.first == 0.0 && x.second == 0.0)
3052
+ {
3053
+ l.subnormalize(mpfr_atan2(l(), yl(), xl(), MPFR_RNDD), MPFR_RNDD); // -pi/2
3054
+ u.subnormalize(mpfr_atan2(u(), yl(), xl(), MPFR_RNDU), MPFR_RNDU); // -pi/2
3055
+ }
3056
+ else if (x.first >= 0.0)
3057
+ {
3058
+ l.subnormalize(mpfr_atan2(l(), yl(), xl(), MPFR_RNDD), MPFR_RNDD);
3059
+ u.subnormalize(mpfr_atan2(u(), yu(), xu(), MPFR_RNDU), MPFR_RNDU);
3060
+ }
3061
+ else if (x.second <= 0.0)
3062
+ {
3063
+ if (y.second == 0.0)
3064
+ {
3065
+ u.subnormalize(mpfr_const_pi(u(), MPFR_RNDU), MPFR_RNDU); // pi
3066
+ l.subnormalize(mpfr_neg(l(), u(), MPFR_RNDD), MPFR_RNDD); // -pi
3067
+ }
3068
+ else
3069
+ {
3070
+ l.subnormalize(mpfr_atan2(l(), yu(), xl(), MPFR_RNDD), MPFR_RNDD);
3071
+ u.subnormalize(mpfr_atan2(u(), yl(), xu(), MPFR_RNDU), MPFR_RNDU);
3072
+ }
3073
+ }
3074
+ else
3075
+ {
3076
+ if (y.second == 0.0)
3077
+ {
3078
+ u.subnormalize(mpfr_const_pi(u(), MPFR_RNDU), MPFR_RNDU); // pi
3079
+ l.subnormalize(mpfr_neg(l(), u(), MPFR_RNDD), MPFR_RNDD); // -pi
3080
+ }
3081
+ else
3082
+ {
3083
+ l.subnormalize(mpfr_atan2(l(), yu(), xl(), MPFR_RNDD), MPFR_RNDD);
3084
+ u.subnormalize(mpfr_atan2(u(), yu(), xu(), MPFR_RNDU), MPFR_RNDU);
3085
+ }
3086
+ }
3087
+ }
3088
+ else if (y.first == 0.0 && y.second == 0.0)
3089
+ {
3090
+ if (x.first >= 0.0)
3091
+ {
3092
+ l.set(0.0, MPFR_RNDD);
3093
+ u.set(0.0, MPFR_RNDU);
3094
+ }
3095
+ else if (x.second <= 0.0)
3096
+ {
3097
+ l.subnormalize(mpfr_const_pi(l(), MPFR_RNDD), MPFR_RNDD); // pi
3098
+ u.subnormalize(mpfr_const_pi(u(), MPFR_RNDU), MPFR_RNDU); // pi
3099
+ }
3100
+ else
3101
+ {
3102
+ l.set(0.0, MPFR_RNDD);
3103
+ u.subnormalize(mpfr_const_pi(u(), MPFR_RNDU), MPFR_RNDU); // pi
3104
+ }
3105
+ }
3106
+ else
3107
+ {
3108
+ if (x.first >= 0.0)
3109
+ {
3110
+ l.subnormalize(mpfr_atan2(l(), yl(), xl(), MPFR_RNDD), MPFR_RNDD);
3111
+ u.subnormalize(mpfr_atan2(u(), yu(), xl(), MPFR_RNDU), MPFR_RNDU);
3112
+ }
3113
+ else
3114
+ {
3115
+ u.subnormalize(mpfr_const_pi(u(), MPFR_RNDU), MPFR_RNDU); // pi
3116
+ l.subnormalize(mpfr_neg(l(), u(), MPFR_RNDD), MPFR_RNDD); // -pi
3117
+ }
3118
+ }
3119
+
3120
+
3121
+ return representation(l.template get<T>(MPFR_RNDD), u.template get<T>(MPFR_RNDU));
3122
+ }
3123
+
3124
+ // atan2 ( bare interval ) mixed type
3125
+ template<typename T>
3126
+ template<typename T1, typename T2>
3127
+ typename mpfr_bin_ieee754_flavor<T>::representation
3128
+ mpfr_bin_ieee754_flavor<T>::atan2(mpfr_bin_ieee754_flavor<T>::representation_type<T1> const& y,
3129
+ mpfr_bin_ieee754_flavor<T>::representation_type<T2> const& x)
3130
+ {
3131
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
3132
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
3133
+
3134
+ if (!mpfr_bin_ieee754_flavor<T1>::is_valid(y) || !mpfr_bin_ieee754_flavor<T2>::is_valid(x))
3135
+ return empty();
3136
+
3137
+ // determine max. precision
3138
+ typedef typename p1788::util::max_precision_type<T,T1,T2>::type T_MAX;
3139
+
3140
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
3141
+ // Error free for floating point inf-sup intervals due to outward rounding
3142
+ return convert_hull(
3143
+ mpfr_bin_ieee754_flavor<T_MAX>::atan2(
3144
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(y),
3145
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
3146
+ )
3147
+ );
3148
+ }
3149
+
3150
+
3151
+ // atan2 ( decorated interval )
3152
+ template<typename T>
3153
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
3154
+ mpfr_bin_ieee754_flavor<T>::atan2(mpfr_bin_ieee754_flavor<T>::representation_dec const& y,
3155
+ mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
3156
+ {
3157
+ if (!is_valid(y) || !is_valid(x) || is_nai(y) || is_nai(x))
3158
+ return nai();
3159
+
3160
+ // compute bare result
3161
+ representation bare = atan2(y.first, x.first);
3162
+
3163
+ // compute decoration
3164
+ p1788::decoration::decoration dec = std::min(
3165
+ std::min(y.second, x.second),
3166
+ (is_member(0.0, y) && is_member(0.0, x)) || is_empty(bare) ? p1788::decoration::decoration::trv :
3167
+ y.first.first < 0.0 && y.first.second >= 0.0 && x.first.first < 0.0 ? p1788::decoration::decoration::def :
3168
+ (y.first.first == 0.0 && x.first.first < 0.0) || !is_common_interval(bare) ? p1788::decoration::decoration::dac :
3169
+ p1788::decoration::decoration::com);
3170
+ return representation_dec(bare, dec);
3171
+ }
3172
+
3173
+ // atan2 ( decorated interval ) mixed type
3174
+ template<typename T>
3175
+ template<typename T1, typename T2>
3176
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
3177
+ mpfr_bin_ieee754_flavor<T>::atan2(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T1> const& y,
3178
+ mpfr_bin_ieee754_flavor<T>::representation_dec_type<T2> const& x)
3179
+ {
3180
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
3181
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
3182
+
3183
+ if (!mpfr_bin_ieee754_flavor<T1>::is_valid(y) || !mpfr_bin_ieee754_flavor<T2>::is_valid(x)
3184
+ || mpfr_bin_ieee754_flavor<T1>::is_nai(y) || mpfr_bin_ieee754_flavor<T2>::is_nai(x))
3185
+ return nai();
3186
+
3187
+ // determine max. precision
3188
+ typedef typename p1788::util::max_precision_type<T,T1,T2>::type T_MAX;
3189
+
3190
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
3191
+ // Error free for floating point inf-sup intervals due to outward rounding
3192
+ return convert_hull(
3193
+ mpfr_bin_ieee754_flavor<T_MAX>::atan2(
3194
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(y),
3195
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
3196
+ )
3197
+ );
3198
+ }
3199
+
3200
+
3201
+ // sinh
3202
+
3203
+ // sinh ( bare interval )
3204
+ template<typename T>
3205
+ typename mpfr_bin_ieee754_flavor<T>::representation
3206
+ mpfr_bin_ieee754_flavor<T>::sinh(mpfr_bin_ieee754_flavor<T>::representation const& x)
3207
+ {
3208
+ if (!is_valid(x) || is_empty(x))
3209
+ return empty();
3210
+
3211
+ mpfr_var::setup();
3212
+
3213
+ mpfr_var xl(x.first, MPFR_RNDD);
3214
+ mpfr_var xu(x.second, MPFR_RNDU);
3215
+
3216
+ xl.subnormalize(mpfr_sinh(xl(), xl(), MPFR_RNDD), MPFR_RNDD);
3217
+ xu.subnormalize(mpfr_sinh(xu(), xu(), MPFR_RNDU), MPFR_RNDU);
3218
+
3219
+ return representation(xl.template get<T>(MPFR_RNDD), xu.template get<T>(MPFR_RNDU));
3220
+ }
3221
+
3222
+
3223
+ // sinh ( bare interval ) mixed type
3224
+ template<typename T>
3225
+ template<typename T_>
3226
+ typename mpfr_bin_ieee754_flavor<T>::representation
3227
+ mpfr_bin_ieee754_flavor<T>::sinh(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& x)
3228
+ {
3229
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
3230
+
3231
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x))
3232
+ return empty();
3233
+
3234
+ // determine max. precision
3235
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
3236
+
3237
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
3238
+ // Error free for floating point inf-sup intervals due to outward rounding
3239
+ return convert_hull(
3240
+ mpfr_bin_ieee754_flavor<T_MAX>::sinh(
3241
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
3242
+ )
3243
+ );
3244
+ }
3245
+
3246
+
3247
+ // sinh ( decorated interval )
3248
+ template<typename T>
3249
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
3250
+ mpfr_bin_ieee754_flavor<T>::sinh(mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
3251
+ {
3252
+ if (!is_valid(x) || is_nai(x))
3253
+ return nai();
3254
+
3255
+ // compute bare result
3256
+ representation bare = sinh(x.first);
3257
+
3258
+ // compute decoration
3259
+ p1788::decoration::decoration dec = std::min(
3260
+ x.second,
3261
+ is_empty(bare) ? p1788::decoration::decoration::trv :
3262
+ is_common_interval(bare) ? p1788::decoration::decoration::com :
3263
+ p1788::decoration::decoration::dac);
3264
+ return representation_dec(bare, dec);
3265
+ }
3266
+
3267
+ // sinh ( decorated interval ) mixed type
3268
+ template<typename T>
3269
+ template<typename T_>
3270
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
3271
+ mpfr_bin_ieee754_flavor<T>::sinh(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& x)
3272
+ {
3273
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
3274
+
3275
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x) || mpfr_bin_ieee754_flavor<T_>::is_nai(x))
3276
+ return nai();
3277
+
3278
+ // determine max. precision
3279
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
3280
+
3281
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
3282
+ // Error free for floating point inf-sup intervals due to outward rounding
3283
+ return convert_hull(
3284
+ mpfr_bin_ieee754_flavor<T_MAX>::sinh(
3285
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
3286
+ )
3287
+ );
3288
+ }
3289
+
3290
+
3291
+ // cosh
3292
+
3293
+ // cosh ( bare interval )
3294
+ template<typename T>
3295
+ typename mpfr_bin_ieee754_flavor<T>::representation
3296
+ mpfr_bin_ieee754_flavor<T>::cosh(mpfr_bin_ieee754_flavor<T>::representation const& x)
3297
+ {
3298
+ if (!is_valid(x) || is_empty(x))
3299
+ return empty();
3300
+
3301
+ mpfr_var::setup();
3302
+
3303
+ if (x.first < 0.0 && x.second > 0.0)
3304
+ {
3305
+ mpfr_var xu(std::max(-x.first, x.second), MPFR_RNDU);
3306
+
3307
+ mpfr_cosh(xu(), xu(), MPFR_RNDU);
3308
+
3309
+ return representation(1.0, xu.template get<T>(MPFR_RNDU));
3310
+ }
3311
+
3312
+ mpfr_var xl(std::min(std::abs(x.first), std::abs(x.second)), MPFR_RNDD);
3313
+ mpfr_var xu(std::max(std::abs(x.first), std::abs(x.second)), MPFR_RNDU);
3314
+
3315
+ xl.subnormalize(mpfr_cosh(xl(), xl(), MPFR_RNDD), MPFR_RNDD);
3316
+ xu.subnormalize(mpfr_cosh(xu(), xu(), MPFR_RNDU), MPFR_RNDU);
3317
+
3318
+ return representation(xl.template get<T>(MPFR_RNDD), xu.template get<T>(MPFR_RNDU));
3319
+ }
3320
+
3321
+ // cosh ( bare interval ) mixed type
3322
+ template<typename T>
3323
+ template<typename T_>
3324
+ typename mpfr_bin_ieee754_flavor<T>::representation
3325
+ mpfr_bin_ieee754_flavor<T>::cosh(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& x)
3326
+ {
3327
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
3328
+
3329
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x))
3330
+ return empty();
3331
+
3332
+ // determine max. precision
3333
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
3334
+
3335
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
3336
+ // Error free for floating point inf-sup intervals due to outward rounding
3337
+ return convert_hull(
3338
+ mpfr_bin_ieee754_flavor<T_MAX>::cosh(
3339
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
3340
+ )
3341
+ );
3342
+ }
3343
+
3344
+
3345
+ // cosh ( decorated interval )
3346
+ template<typename T>
3347
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
3348
+ mpfr_bin_ieee754_flavor<T>::cosh(mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
3349
+ {
3350
+ if (!is_valid(x) || is_nai(x))
3351
+ return nai();
3352
+
3353
+ // compute bare result
3354
+ representation bare = cosh(x.first);
3355
+
3356
+ // compute decoration
3357
+ p1788::decoration::decoration dec = std::min(
3358
+ x.second,
3359
+ is_empty(bare) ? p1788::decoration::decoration::trv :
3360
+ is_common_interval(bare) ? p1788::decoration::decoration::com :
3361
+ p1788::decoration::decoration::dac);
3362
+ return representation_dec(bare, dec);
3363
+ }
3364
+
3365
+ // cosh ( decorated interval ) mixed type
3366
+ template<typename T>
3367
+ template<typename T_>
3368
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
3369
+ mpfr_bin_ieee754_flavor<T>::cosh(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& x)
3370
+ {
3371
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
3372
+
3373
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x) || mpfr_bin_ieee754_flavor<T_>::is_nai(x))
3374
+ return nai();
3375
+
3376
+ // determine max. precision
3377
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
3378
+
3379
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
3380
+ // Error free for floating point inf-sup intervals due to outward rounding
3381
+ return convert_hull(
3382
+ mpfr_bin_ieee754_flavor<T_MAX>::cosh(
3383
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
3384
+ )
3385
+ );
3386
+ }
3387
+
3388
+
3389
+ // tanh
3390
+
3391
+ // tanh ( bare interval )
3392
+ template<typename T>
3393
+ typename mpfr_bin_ieee754_flavor<T>::representation
3394
+ mpfr_bin_ieee754_flavor<T>::tanh(mpfr_bin_ieee754_flavor<T>::representation const& x)
3395
+ {
3396
+ if (!is_valid(x) || is_empty(x))
3397
+ return empty();
3398
+
3399
+ mpfr_var::setup();
3400
+
3401
+ mpfr_var xl(x.first, MPFR_RNDD);
3402
+ mpfr_var xu(x.second, MPFR_RNDU);
3403
+
3404
+ xl.subnormalize(mpfr_tanh(xl(), xl(), MPFR_RNDD), MPFR_RNDD);
3405
+ xu.subnormalize(mpfr_tanh(xu(), xu(), MPFR_RNDU), MPFR_RNDU);
3406
+
3407
+ return representation(xl.template get<T>(MPFR_RNDD), xu.template get<T>(MPFR_RNDU));
3408
+ }
3409
+
3410
+ // tanh ( bare interval ) mixed type
3411
+ template<typename T>
3412
+ template<typename T_>
3413
+ typename mpfr_bin_ieee754_flavor<T>::representation
3414
+ mpfr_bin_ieee754_flavor<T>::tanh(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& x)
3415
+ {
3416
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
3417
+
3418
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x))
3419
+ return empty();
3420
+
3421
+ // determine max. precision
3422
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
3423
+
3424
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
3425
+ // Error free for floating point inf-sup intervals due to outward rounding
3426
+ return convert_hull(
3427
+ mpfr_bin_ieee754_flavor<T_MAX>::tanh(
3428
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
3429
+ )
3430
+ );
3431
+ }
3432
+
3433
+
3434
+ // tanh ( decorated interval )
3435
+ template<typename T>
3436
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
3437
+ mpfr_bin_ieee754_flavor<T>::tanh(mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
3438
+ {
3439
+ if (!is_valid(x) || is_nai(x))
3440
+ return nai();
3441
+
3442
+ // compute bare result
3443
+ representation bare = tanh(x.first);
3444
+
3445
+ // compute decoration
3446
+ p1788::decoration::decoration dec = std::min(
3447
+ x.second,
3448
+ is_empty(bare) ? p1788::decoration::decoration::trv
3449
+ : p1788::decoration::decoration::com);
3450
+ return representation_dec(bare, dec);
3451
+ }
3452
+
3453
+ // tanh ( decorated interval ) mixed type
3454
+ template<typename T>
3455
+ template<typename T_>
3456
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
3457
+ mpfr_bin_ieee754_flavor<T>::tanh(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& x)
3458
+ {
3459
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
3460
+
3461
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x) || mpfr_bin_ieee754_flavor<T_>::is_nai(x))
3462
+ return nai();
3463
+
3464
+ // determine max. precision
3465
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
3466
+
3467
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
3468
+ // Error free for floating point inf-sup intervals due to outward rounding
3469
+ return convert_hull(
3470
+ mpfr_bin_ieee754_flavor<T_MAX>::tanh(
3471
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
3472
+ )
3473
+ );
3474
+ }
3475
+
3476
+
3477
+ // asinh
3478
+
3479
+ // asinh ( bare interval )
3480
+ template<typename T>
3481
+ typename mpfr_bin_ieee754_flavor<T>::representation
3482
+ mpfr_bin_ieee754_flavor<T>::asinh(mpfr_bin_ieee754_flavor<T>::representation const& x)
3483
+ {
3484
+ if (!is_valid(x) || is_empty(x))
3485
+ return empty();
3486
+
3487
+ mpfr_var::setup();
3488
+
3489
+ mpfr_var xl(x.first, MPFR_RNDD);
3490
+ mpfr_var xu(x.second, MPFR_RNDU);
3491
+
3492
+ xl.subnormalize(mpfr_asinh(xl(), xl(), MPFR_RNDD), MPFR_RNDD);
3493
+ xu.subnormalize(mpfr_asinh(xu(), xu(), MPFR_RNDU), MPFR_RNDU);
3494
+
3495
+ return representation(xl.template get<T>(MPFR_RNDD), xu.template get<T>(MPFR_RNDU));
3496
+ }
3497
+
3498
+ // asinh ( bare interval ) mixed type
3499
+ template<typename T>
3500
+ template<typename T_>
3501
+ typename mpfr_bin_ieee754_flavor<T>::representation
3502
+ mpfr_bin_ieee754_flavor<T>::asinh(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& x)
3503
+ {
3504
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
3505
+
3506
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x))
3507
+ return empty();
3508
+
3509
+ // determine max. precision
3510
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
3511
+
3512
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
3513
+ // Error free for floating point inf-sup intervals due to outward rounding
3514
+ return convert_hull(
3515
+ mpfr_bin_ieee754_flavor<T_MAX>::asinh(
3516
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
3517
+ )
3518
+ );
3519
+ }
3520
+
3521
+
3522
+ // asinh ( decorated interval )
3523
+ template<typename T>
3524
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
3525
+ mpfr_bin_ieee754_flavor<T>::asinh(mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
3526
+ {
3527
+ if (!is_valid(x) || is_nai(x))
3528
+ return nai();
3529
+
3530
+ // compute bare result
3531
+ representation bare = asinh(x.first);
3532
+
3533
+ // compute decoration
3534
+ p1788::decoration::decoration dec = std::min(
3535
+ x.second,
3536
+ is_empty(bare) ? p1788::decoration::decoration::trv :
3537
+ is_common_interval(bare) ? p1788::decoration::decoration::com :
3538
+ p1788::decoration::decoration::dac);
3539
+ return representation_dec(bare, dec);
3540
+ }
3541
+
3542
+ // asinh ( decorated interval ) mixed type
3543
+ template<typename T>
3544
+ template<typename T_>
3545
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
3546
+ mpfr_bin_ieee754_flavor<T>::asinh(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& x)
3547
+ {
3548
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
3549
+
3550
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x) || mpfr_bin_ieee754_flavor<T_>::is_nai(x))
3551
+ return nai();
3552
+
3553
+ // determine max. precision
3554
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
3555
+
3556
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
3557
+ // Error free for floating point inf-sup intervals due to outward rounding
3558
+ return convert_hull(
3559
+ mpfr_bin_ieee754_flavor<T_MAX>::asinh(
3560
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
3561
+ )
3562
+ );
3563
+ }
3564
+
3565
+
3566
+ // acosh
3567
+
3568
+ // acosh ( bare interval )
3569
+ template<typename T>
3570
+ typename mpfr_bin_ieee754_flavor<T>::representation
3571
+ mpfr_bin_ieee754_flavor<T>::acosh(mpfr_bin_ieee754_flavor<T>::representation const& x)
3572
+ {
3573
+ if (!is_valid(x) || is_empty(x) || x.second < 1.0)
3574
+ return empty();
3575
+
3576
+ mpfr_var::setup();
3577
+
3578
+ mpfr_var xl(x.first < 1.0 ? 1.0 : x.first, MPFR_RNDD);
3579
+ mpfr_var xu(x.second, MPFR_RNDU);
3580
+
3581
+ xl.subnormalize(mpfr_acosh(xl(), xl(), MPFR_RNDD), MPFR_RNDD);
3582
+ xu.subnormalize(mpfr_acosh(xu(), xu(), MPFR_RNDU), MPFR_RNDU);
3583
+
3584
+ return representation(xl.template get<T>(MPFR_RNDD), xu.template get<T>(MPFR_RNDU));
3585
+ }
3586
+
3587
+ // acosh ( bare interval ) mixed type
3588
+ template<typename T>
3589
+ template<typename T_>
3590
+ typename mpfr_bin_ieee754_flavor<T>::representation
3591
+ mpfr_bin_ieee754_flavor<T>::acosh(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& x)
3592
+ {
3593
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
3594
+
3595
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x))
3596
+ return empty();
3597
+
3598
+ // determine max. precision
3599
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
3600
+
3601
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
3602
+ // Error free for floating point inf-sup intervals due to outward rounding
3603
+ return convert_hull(
3604
+ mpfr_bin_ieee754_flavor<T_MAX>::acosh(
3605
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
3606
+ )
3607
+ );
3608
+ }
3609
+
3610
+
3611
+ // acosh ( decorated interval )
3612
+ template<typename T>
3613
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
3614
+ mpfr_bin_ieee754_flavor<T>::acosh(mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
3615
+ {
3616
+ if (!is_valid(x) || is_nai(x))
3617
+ return nai();
3618
+
3619
+ // compute bare result
3620
+ representation bare = acosh(x.first);
3621
+
3622
+ // compute decoration
3623
+ p1788::decoration::decoration dec = std::min(
3624
+ x.second,
3625
+ x.first.first < 1.0 || is_empty(bare) ? p1788::decoration::decoration::trv :
3626
+ is_common_interval(bare) ? p1788::decoration::decoration::com :
3627
+ p1788::decoration::decoration::dac);
3628
+ return representation_dec(bare, dec);
3629
+ }
3630
+
3631
+ // acosh ( decorated interval ) mixed type
3632
+ template<typename T>
3633
+ template<typename T_>
3634
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
3635
+ mpfr_bin_ieee754_flavor<T>::acosh(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& x)
3636
+ {
3637
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
3638
+
3639
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x) || mpfr_bin_ieee754_flavor<T_>::is_nai(x))
3640
+ return nai();
3641
+
3642
+ // determine max. precision
3643
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
3644
+
3645
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
3646
+ // Error free for floating point inf-sup intervals due to outward rounding
3647
+ return convert_hull(
3648
+ mpfr_bin_ieee754_flavor<T_MAX>::acosh(
3649
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
3650
+ )
3651
+ );
3652
+ }
3653
+
3654
+
3655
+ // atanh
3656
+
3657
+ // atanh ( bare interval )
3658
+ template<typename T>
3659
+ typename mpfr_bin_ieee754_flavor<T>::representation
3660
+ mpfr_bin_ieee754_flavor<T>::atanh(mpfr_bin_ieee754_flavor<T>::representation const& x)
3661
+ {
3662
+ if (!is_valid(x) || is_empty(x) || x.second <= -1.0 || x.first >= 1.0)
3663
+ return empty();
3664
+
3665
+ mpfr_var::setup();
3666
+
3667
+ mpfr_var xl(x.first < -1.0 ? -1.0 : x.first, MPFR_RNDD);
3668
+ mpfr_var xu(x.second > 1.0 ? 1.0 : x.second, MPFR_RNDU);
3669
+
3670
+ xl.subnormalize(mpfr_atanh(xl(), xl(), MPFR_RNDD), MPFR_RNDD);
3671
+ xu.subnormalize(mpfr_atanh(xu(), xu(), MPFR_RNDU), MPFR_RNDU);
3672
+
3673
+ return representation(xl.template get<T>(MPFR_RNDD), xu.template get<T>(MPFR_RNDU));
3674
+ }
3675
+
3676
+ // atanh ( bare interval ) mixed type
3677
+ template<typename T>
3678
+ template<typename T_>
3679
+ typename mpfr_bin_ieee754_flavor<T>::representation
3680
+ mpfr_bin_ieee754_flavor<T>::atanh(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& x)
3681
+ {
3682
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
3683
+
3684
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x))
3685
+ return empty();
3686
+
3687
+ // determine max. precision
3688
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
3689
+
3690
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
3691
+ // Error free for floating point inf-sup intervals due to outward rounding
3692
+ return convert_hull(
3693
+ mpfr_bin_ieee754_flavor<T_MAX>::atanh(
3694
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
3695
+ )
3696
+ );
3697
+ }
3698
+
3699
+
3700
+ // atanh ( decorated interval )
3701
+ template<typename T>
3702
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
3703
+ mpfr_bin_ieee754_flavor<T>::atanh(mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
3704
+ {
3705
+ if (!is_valid(x) || is_nai(x))
3706
+ return nai();
3707
+
3708
+ // compute bare result
3709
+ representation bare = atanh(x.first);
3710
+
3711
+ // compute decoration
3712
+ p1788::decoration::decoration dec = std::min(
3713
+ x.second,
3714
+ x.first.first <= -1.0 || x.first.second >= 1.0 || is_empty(bare) ? p1788::decoration::decoration::trv :
3715
+ is_common_interval(bare) ? p1788::decoration::decoration::com :
3716
+ p1788::decoration::decoration::dac);
3717
+ return representation_dec(bare, dec);
3718
+ }
3719
+
3720
+ // atanh ( decorated interval ) mixed type
3721
+ template<typename T>
3722
+ template<typename T_>
3723
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
3724
+ mpfr_bin_ieee754_flavor<T>::atanh(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& x)
3725
+ {
3726
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
3727
+
3728
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x) || mpfr_bin_ieee754_flavor<T_>::is_nai(x))
3729
+ return nai();
3730
+
3731
+ // determine max. precision
3732
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
3733
+
3734
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
3735
+ // Error free for floating point inf-sup intervals due to outward rounding
3736
+ return convert_hull(
3737
+ mpfr_bin_ieee754_flavor<T_MAX>::atanh(
3738
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
3739
+ )
3740
+ );
3741
+ }
3742
+
3743
+
3744
+ // sign
3745
+
3746
+ // sign ( bare interval )
3747
+ template<typename T>
3748
+ typename mpfr_bin_ieee754_flavor<T>::representation
3749
+ mpfr_bin_ieee754_flavor<T>::sign(mpfr_bin_ieee754_flavor<T>::representation const& x)
3750
+ {
3751
+ if (!is_valid(x) || is_empty(x))
3752
+ return empty();
3753
+
3754
+ return representation((x.first < 0.0) ? -1.0 : ((x.first == 0.0) ? 0.0 : 1.0),
3755
+ (x.second < 0.0) ? -1.0 : ((x.second == 0.0) ? 0.0 : 1.0));
3756
+ }
3757
+
3758
+ // sign ( bare interval ) mixed type
3759
+ template<typename T>
3760
+ template<typename T_>
3761
+ typename mpfr_bin_ieee754_flavor<T>::representation
3762
+ mpfr_bin_ieee754_flavor<T>::sign(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& x)
3763
+ {
3764
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
3765
+
3766
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x))
3767
+ return empty();
3768
+
3769
+ // determine max. precision
3770
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
3771
+
3772
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
3773
+ // Error free for floating point inf-sup intervals due to outward rounding
3774
+ return convert_hull(
3775
+ mpfr_bin_ieee754_flavor<T_MAX>::sign(
3776
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
3777
+ )
3778
+ );
3779
+ }
3780
+
3781
+
3782
+ // sign ( decorated interval )
3783
+ template<typename T>
3784
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
3785
+ mpfr_bin_ieee754_flavor<T>::sign(mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
3786
+ {
3787
+ if (!is_valid(x) || is_nai(x))
3788
+ return nai();
3789
+
3790
+ // compute bare result
3791
+ representation bare = sign(x.first);
3792
+
3793
+ // compute decoration
3794
+ p1788::decoration::decoration dec = std::min(
3795
+ x.second,
3796
+ is_empty(bare) ? p1788::decoration::decoration::trv :
3797
+ !is_singleton(bare) ? p1788::decoration::decoration::def :
3798
+ is_member(0.0, x) ? p1788::decoration::decoration::dac :
3799
+ p1788::decoration::decoration::com);
3800
+ return representation_dec(bare, dec);
3801
+ }
3802
+
3803
+ // sign ( decorated interval ) mixed type
3804
+ template<typename T>
3805
+ template<typename T_>
3806
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
3807
+ mpfr_bin_ieee754_flavor<T>::sign(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& x)
3808
+ {
3809
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
3810
+
3811
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x) || mpfr_bin_ieee754_flavor<T_>::is_nai(x))
3812
+ return nai();
3813
+
3814
+ // determine max. precision
3815
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
3816
+
3817
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
3818
+ // Error free for floating point inf-sup intervals due to outward rounding
3819
+ return convert_hull(
3820
+ mpfr_bin_ieee754_flavor<T_MAX>::sign(
3821
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
3822
+ )
3823
+ );
3824
+ }
3825
+
3826
+
3827
+
3828
+ // ceil
3829
+
3830
+ // ceil ( bare interval )
3831
+ template<typename T>
3832
+ typename mpfr_bin_ieee754_flavor<T>::representation
3833
+ mpfr_bin_ieee754_flavor<T>::ceil(mpfr_bin_ieee754_flavor<T>::representation const& x)
3834
+ {
3835
+ if (!is_valid(x) || is_empty(x))
3836
+ return empty();
3837
+
3838
+ return representation(std::ceil(x.first), std::ceil(x.second));
3839
+ }
3840
+
3841
+ // ceil ( bare interval ) mixed type
3842
+ template<typename T>
3843
+ template<typename T_>
3844
+ typename mpfr_bin_ieee754_flavor<T>::representation
3845
+ mpfr_bin_ieee754_flavor<T>::ceil(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& x)
3846
+ {
3847
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
3848
+
3849
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x))
3850
+ return empty();
3851
+
3852
+ // determine max. precision
3853
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
3854
+
3855
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
3856
+ // Error free for floating point inf-sup intervals due to outward rounding
3857
+ return convert_hull(
3858
+ mpfr_bin_ieee754_flavor<T_MAX>::ceil(
3859
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
3860
+ )
3861
+ );
3862
+ }
3863
+
3864
+
3865
+ // ceil ( decorated interval )
3866
+ template<typename T>
3867
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
3868
+ mpfr_bin_ieee754_flavor<T>::ceil(mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
3869
+ {
3870
+ if (!is_valid(x) || is_nai(x))
3871
+ return nai();
3872
+
3873
+ // compute bare result
3874
+ representation bare = ceil(x.first);
3875
+
3876
+ // compute decoration
3877
+ p1788::decoration::decoration dec = std::min(
3878
+ x.second,
3879
+ is_empty(bare) ? p1788::decoration::decoration::trv :
3880
+ !is_singleton(bare) ? p1788::decoration::decoration::def :
3881
+ x.first.second == bare.second ? p1788::decoration::decoration::dac :
3882
+ p1788::decoration::decoration::com);
3883
+ return representation_dec(bare, dec);
3884
+ }
3885
+
3886
+ // ceil ( decorated interval ) mixed type
3887
+ template<typename T>
3888
+ template<typename T_>
3889
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
3890
+ mpfr_bin_ieee754_flavor<T>::ceil(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& x)
3891
+ {
3892
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
3893
+
3894
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x) || mpfr_bin_ieee754_flavor<T_>::is_nai(x))
3895
+ return nai();
3896
+
3897
+ // determine max. precision
3898
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
3899
+
3900
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
3901
+ // Error free for floating point inf-sup intervals due to outward rounding
3902
+ return convert_hull(
3903
+ mpfr_bin_ieee754_flavor<T_MAX>::ceil(
3904
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
3905
+ )
3906
+ );
3907
+ }
3908
+
3909
+
3910
+ // floor
3911
+
3912
+ // floor ( bare interval )
3913
+ template<typename T>
3914
+ typename mpfr_bin_ieee754_flavor<T>::representation
3915
+ mpfr_bin_ieee754_flavor<T>::floor(mpfr_bin_ieee754_flavor<T>::representation const& x)
3916
+ {
3917
+ if (!is_valid(x) || is_empty(x))
3918
+ return empty();
3919
+
3920
+ return representation(std::floor(x.first), std::floor(x.second));
3921
+ }
3922
+
3923
+ // floor ( bare interval ) mixed type
3924
+ template<typename T>
3925
+ template<typename T_>
3926
+ typename mpfr_bin_ieee754_flavor<T>::representation
3927
+ mpfr_bin_ieee754_flavor<T>::floor(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& x)
3928
+ {
3929
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
3930
+
3931
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x))
3932
+ return empty();
3933
+
3934
+ // determine max. precision
3935
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
3936
+
3937
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
3938
+ // Error free for floating point inf-sup intervals due to outward rounding
3939
+ return convert_hull(
3940
+ mpfr_bin_ieee754_flavor<T_MAX>::floor(
3941
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
3942
+ )
3943
+ );
3944
+ }
3945
+
3946
+
3947
+ // floor ( decorated interval )
3948
+ template<typename T>
3949
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
3950
+ mpfr_bin_ieee754_flavor<T>::floor(mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
3951
+ {
3952
+ if (!is_valid(x) || is_nai(x))
3953
+ return nai();
3954
+
3955
+ // compute bare result
3956
+ representation bare = floor(x.first);
3957
+
3958
+ // compute decoration
3959
+ p1788::decoration::decoration dec = std::min(
3960
+ x.second,
3961
+ is_empty(bare) ? p1788::decoration::decoration::trv :
3962
+ !is_singleton(bare) ? p1788::decoration::decoration::def :
3963
+ x.first.first == bare.first ? p1788::decoration::decoration::dac :
3964
+ p1788::decoration::decoration::com);
3965
+ return representation_dec(bare, dec);
3966
+ }
3967
+
3968
+ // floor ( decorated interval ) mixed type
3969
+ template<typename T>
3970
+ template<typename T_>
3971
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
3972
+ mpfr_bin_ieee754_flavor<T>::floor(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& x)
3973
+ {
3974
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
3975
+
3976
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x) || mpfr_bin_ieee754_flavor<T_>::is_nai(x))
3977
+ return nai();
3978
+
3979
+ // determine max. precision
3980
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
3981
+
3982
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
3983
+ // Error free for floating point inf-sup intervals due to outward rounding
3984
+ return convert_hull(
3985
+ mpfr_bin_ieee754_flavor<T_MAX>::floor(
3986
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
3987
+ )
3988
+ );
3989
+ }
3990
+
3991
+
3992
+ // trunc
3993
+
3994
+ // trunc ( bare interval )
3995
+ template<typename T>
3996
+ typename mpfr_bin_ieee754_flavor<T>::representation
3997
+ mpfr_bin_ieee754_flavor<T>::trunc(mpfr_bin_ieee754_flavor<T>::representation const& x)
3998
+ {
3999
+ if (!is_valid(x) || is_empty(x))
4000
+ return empty();
4001
+
4002
+ return representation(std::trunc(x.first), std::trunc(x.second));
4003
+ }
4004
+
4005
+ // trunc ( bare interval ) mixed type
4006
+ template<typename T>
4007
+ template<typename T_>
4008
+ typename mpfr_bin_ieee754_flavor<T>::representation
4009
+ mpfr_bin_ieee754_flavor<T>::trunc(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& x)
4010
+ {
4011
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
4012
+
4013
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x))
4014
+ return empty();
4015
+
4016
+ // determine max. precision
4017
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
4018
+
4019
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
4020
+ // Error free for floating point inf-sup intervals due to outward rounding
4021
+ return convert_hull(
4022
+ mpfr_bin_ieee754_flavor<T_MAX>::trunc(
4023
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
4024
+ )
4025
+ );
4026
+ }
4027
+
4028
+
4029
+ // trunc ( decorated interval )
4030
+ template<typename T>
4031
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
4032
+ mpfr_bin_ieee754_flavor<T>::trunc(mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
4033
+ {
4034
+ if (!is_valid(x) || is_nai(x))
4035
+ return nai();
4036
+
4037
+ // compute bare result
4038
+ representation bare = trunc(x.first);
4039
+
4040
+ // compute decoration
4041
+ p1788::decoration::decoration dec = std::min(
4042
+ x.second,
4043
+ is_empty(bare) ? p1788::decoration::decoration::trv :
4044
+ !is_singleton(bare) ? p1788::decoration::decoration::def :
4045
+ (x.first.first != 0.0 && x.first.first == bare.first)
4046
+ || (x.first.second != 0.0 && x.first.second == bare.second) ? p1788::decoration::decoration::dac :
4047
+ p1788::decoration::decoration::com);
4048
+ return representation_dec(bare, dec);
4049
+ }
4050
+
4051
+ // trunc ( decorated interval ) mixed type
4052
+ template<typename T>
4053
+ template<typename T_>
4054
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
4055
+ mpfr_bin_ieee754_flavor<T>::trunc(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& x)
4056
+ {
4057
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
4058
+
4059
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x) || mpfr_bin_ieee754_flavor<T_>::is_nai(x))
4060
+ return nai();
4061
+
4062
+ // determine max. precision
4063
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
4064
+
4065
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
4066
+ // Error free for floating point inf-sup intervals due to outward rounding
4067
+ return convert_hull(
4068
+ mpfr_bin_ieee754_flavor<T_MAX>::trunc(
4069
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
4070
+ )
4071
+ );
4072
+ }
4073
+
4074
+
4075
+ // round_ties_to_even
4076
+
4077
+ // round_ties_to_even ( bare interval )
4078
+ template<typename T>
4079
+ typename mpfr_bin_ieee754_flavor<T>::representation
4080
+ mpfr_bin_ieee754_flavor<T>::round_ties_to_even(mpfr_bin_ieee754_flavor<T>::representation const& x)
4081
+ {
4082
+ if (!is_valid(x) || is_empty(x))
4083
+ return empty();
4084
+
4085
+ class rnd_controll
4086
+ {
4087
+ int rnd_;
4088
+ public:
4089
+ rnd_controll() : rnd_(std::fegetround())
4090
+ {
4091
+ std::fesetround(FE_TONEAREST);
4092
+ }
4093
+
4094
+ ~rnd_controll()
4095
+ {
4096
+ std::fesetround(rnd_);
4097
+ }
4098
+ } rnd;
4099
+
4100
+ return representation(std::nearbyint(x.first), std::nearbyint(x.second));
4101
+ }
4102
+
4103
+ // round_ties_to_even ( bare interval ) mixed type
4104
+ template<typename T>
4105
+ template<typename T_>
4106
+ typename mpfr_bin_ieee754_flavor<T>::representation
4107
+ mpfr_bin_ieee754_flavor<T>::round_ties_to_even(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& x)
4108
+ {
4109
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
4110
+
4111
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x))
4112
+ return empty();
4113
+
4114
+ // determine max. precision
4115
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
4116
+
4117
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
4118
+ // Error free for floating point inf-sup intervals due to outward rounding
4119
+ return convert_hull(
4120
+ mpfr_bin_ieee754_flavor<T_MAX>::round_ties_to_even(
4121
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
4122
+ )
4123
+ );
4124
+ }
4125
+
4126
+
4127
+ // round_ties_to_even ( decorated interval )
4128
+ template<typename T>
4129
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
4130
+ mpfr_bin_ieee754_flavor<T>::round_ties_to_even(mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
4131
+ {
4132
+ if (!is_valid(x) || is_nai(x))
4133
+ return nai();
4134
+
4135
+ // compute bare result
4136
+ representation bare = round_ties_to_even(x.first);
4137
+
4138
+ // compute decoration
4139
+ p1788::decoration::decoration dec = std::min(
4140
+ x.second,
4141
+ is_empty(bare) ? p1788::decoration::decoration::trv :
4142
+ !is_singleton(bare) ? p1788::decoration::decoration::def :
4143
+ std::abs(x.first.first) - std::trunc(std::abs(x.first.first)) == 0.5 // if x == 0.5 => trunc(x) == 0.0 => exact
4144
+ || std::abs(x.first.second) - std::trunc(std::abs(x.first.second)) == 0.5 // if x > 1 => trunc(x) > 1 => tunc(x) <= x <= 2 trunc(x) => exact
4145
+ ? p1788::decoration::decoration::dac : p1788::decoration::decoration::com);
4146
+ return representation_dec(bare, dec);
4147
+ }
4148
+
4149
+ // round_ties_to_even ( decorated interval ) mixed type
4150
+ template<typename T>
4151
+ template<typename T_>
4152
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
4153
+ mpfr_bin_ieee754_flavor<T>::round_ties_to_even(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& x)
4154
+ {
4155
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
4156
+
4157
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x) || mpfr_bin_ieee754_flavor<T_>::is_nai(x))
4158
+ return nai();
4159
+
4160
+ // determine max. precision
4161
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
4162
+
4163
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
4164
+ // Error free for floating point inf-sup intervals due to outward rounding
4165
+ return convert_hull(
4166
+ mpfr_bin_ieee754_flavor<T_MAX>::round_ties_to_even(
4167
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
4168
+ )
4169
+ );
4170
+ }
4171
+
4172
+
4173
+ // round_ties_to_away
4174
+
4175
+ // round_ties_to_away ( bare interval )
4176
+ template<typename T>
4177
+ typename mpfr_bin_ieee754_flavor<T>::representation
4178
+ mpfr_bin_ieee754_flavor<T>::round_ties_to_away(mpfr_bin_ieee754_flavor<T>::representation const& x)
4179
+ {
4180
+ if (!is_valid(x) || is_empty(x))
4181
+ return empty();
4182
+
4183
+ return representation(std::round(x.first), std::round(x.second));
4184
+ }
4185
+
4186
+ // round_ties_to_away ( bare interval ) mixed type
4187
+ template<typename T>
4188
+ template<typename T_>
4189
+ typename mpfr_bin_ieee754_flavor<T>::representation
4190
+ mpfr_bin_ieee754_flavor<T>::round_ties_to_away(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& x)
4191
+ {
4192
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
4193
+
4194
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x))
4195
+ return empty();
4196
+
4197
+ // determine max. precision
4198
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
4199
+
4200
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
4201
+ // Error free for floating point inf-sup intervals due to outward rounding
4202
+ return convert_hull(
4203
+ mpfr_bin_ieee754_flavor<T_MAX>::round_ties_to_away(
4204
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
4205
+ )
4206
+ );
4207
+ }
4208
+
4209
+
4210
+ // round_ties_to_away ( decorated interval )
4211
+ template<typename T>
4212
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
4213
+ mpfr_bin_ieee754_flavor<T>::round_ties_to_away(mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
4214
+ {
4215
+ if (!is_valid(x) || is_nai(x))
4216
+ return nai();
4217
+
4218
+ // compute bare result
4219
+ representation bare = round_ties_to_away(x.first);
4220
+
4221
+ // compute decoration
4222
+ p1788::decoration::decoration dec = std::min(
4223
+ x.second,
4224
+ is_empty(bare) ? p1788::decoration::decoration::trv :
4225
+ !is_singleton(bare) ? p1788::decoration::decoration::def :
4226
+ std::abs(x.first.first) - std::trunc(std::abs(x.first.first)) == 0.5 // if x == 0.5 => trunc(x) == 0.0 => exact
4227
+ || std::abs(x.first.second) - std::trunc(std::abs(x.first.second)) == 0.5 // if x > 1 => trunc(x) > 1 => tunc(x) <= x <= 2 * trunc(x) => exact
4228
+ ? p1788::decoration::decoration::dac : p1788::decoration::decoration::com);
4229
+ return representation_dec(bare, dec);
4230
+ }
4231
+
4232
+ // round_ties_to_away ( decorated interval ) mixed type
4233
+ template<typename T>
4234
+ template<typename T_>
4235
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
4236
+ mpfr_bin_ieee754_flavor<T>::round_ties_to_away(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& x)
4237
+ {
4238
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
4239
+
4240
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x) || mpfr_bin_ieee754_flavor<T_>::is_nai(x))
4241
+ return nai();
4242
+
4243
+ // determine max. precision
4244
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
4245
+
4246
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
4247
+ // Error free for floating point inf-sup intervals due to outward rounding
4248
+ return convert_hull(
4249
+ mpfr_bin_ieee754_flavor<T_MAX>::round_ties_to_away(
4250
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
4251
+ )
4252
+ );
4253
+ }
4254
+
4255
+
4256
+ // abs
4257
+
4258
+ // abs ( bare interval )
4259
+ template<typename T>
4260
+ typename mpfr_bin_ieee754_flavor<T>::representation
4261
+ mpfr_bin_ieee754_flavor<T>::abs(mpfr_bin_ieee754_flavor<T>::representation const& x)
4262
+ {
4263
+ if (!is_valid(x) || is_empty(x))
4264
+ return empty();
4265
+
4266
+ if (x.first >= 0.0)
4267
+ return x;
4268
+
4269
+ if (x.second <= 0.0)
4270
+ return representation(std::abs(x.second), std::abs(x.first));
4271
+
4272
+ return representation(0.0, std::max(std::abs(x.first), x.second));
4273
+ }
4274
+
4275
+ // abs ( bare interval ) mixed type
4276
+ template<typename T>
4277
+ template<typename T_>
4278
+ typename mpfr_bin_ieee754_flavor<T>::representation
4279
+ mpfr_bin_ieee754_flavor<T>::abs(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& x)
4280
+ {
4281
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
4282
+
4283
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x))
4284
+ return empty();
4285
+
4286
+ // determine max. precision
4287
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
4288
+
4289
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
4290
+ // Error free for floating point inf-sup intervals due to outward rounding
4291
+ return convert_hull(
4292
+ mpfr_bin_ieee754_flavor<T_MAX>::abs(
4293
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
4294
+ )
4295
+ );
4296
+ }
4297
+
4298
+
4299
+ // abs ( decorated interval )
4300
+ template<typename T>
4301
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
4302
+ mpfr_bin_ieee754_flavor<T>::abs(mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
4303
+ {
4304
+ if (!is_valid(x) || is_nai(x))
4305
+ return nai();
4306
+
4307
+ // compute bare result
4308
+ representation bare = abs(x.first);
4309
+
4310
+ // compute decoration
4311
+ p1788::decoration::decoration dec = std::min(
4312
+ x.second,
4313
+ is_empty(bare) ? p1788::decoration::decoration::trv :
4314
+ is_common_interval(bare) ? p1788::decoration::decoration::com :
4315
+ p1788::decoration::decoration::dac);
4316
+ return representation_dec(bare, dec);
4317
+ }
4318
+
4319
+ // abs ( decorated interval ) mixed type
4320
+ template<typename T>
4321
+ template<typename T_>
4322
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
4323
+ mpfr_bin_ieee754_flavor<T>::abs(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& x)
4324
+ {
4325
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
4326
+
4327
+ if (!mpfr_bin_ieee754_flavor<T_>::is_valid(x) || mpfr_bin_ieee754_flavor<T_>::is_nai(x))
4328
+ return nai();
4329
+
4330
+ // determine max. precision
4331
+ typedef typename p1788::util::max_precision_type<T,T_>::type T_MAX;
4332
+
4333
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
4334
+ // Error free for floating point inf-sup intervals due to outward rounding
4335
+ return convert_hull(
4336
+ mpfr_bin_ieee754_flavor<T_MAX>::abs(
4337
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
4338
+ )
4339
+ );
4340
+ }
4341
+
4342
+
4343
+ // min
4344
+
4345
+ // min ( bare interval )
4346
+ template<typename T>
4347
+ typename mpfr_bin_ieee754_flavor<T>::representation
4348
+ mpfr_bin_ieee754_flavor<T>::min(mpfr_bin_ieee754_flavor<T>::representation const& x,
4349
+ mpfr_bin_ieee754_flavor<T>::representation const& y)
4350
+ {
4351
+ if (!is_valid(x) || !is_valid(y) || is_empty(x) || is_empty(y))
4352
+ return empty();
4353
+
4354
+ return representation(std::min(x.first, y.first), std::min(x.second, y.second));
4355
+ }
4356
+
4357
+ // min ( bare interval ) mixed type
4358
+ template<typename T>
4359
+ template<typename T1, typename T2>
4360
+ typename mpfr_bin_ieee754_flavor<T>::representation
4361
+ mpfr_bin_ieee754_flavor<T>::min(mpfr_bin_ieee754_flavor<T>::representation_type<T1> const& x,
4362
+ mpfr_bin_ieee754_flavor<T>::representation_type<T2> const& y)
4363
+ {
4364
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
4365
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
4366
+
4367
+ if (!mpfr_bin_ieee754_flavor<T1>::is_valid(x) || !mpfr_bin_ieee754_flavor<T2>::is_valid(y))
4368
+ return empty();
4369
+
4370
+ // determine max. precision
4371
+ typedef typename p1788::util::max_precision_type<T,T1,T2>::type T_MAX;
4372
+
4373
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
4374
+ // Error free for floating point inf-sup intervals due to outward rounding
4375
+ return convert_hull(
4376
+ mpfr_bin_ieee754_flavor<T_MAX>::min(
4377
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x),
4378
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(y)
4379
+ )
4380
+ );
4381
+ }
4382
+
4383
+
4384
+ // min ( decorated interval )
4385
+ template<typename T>
4386
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
4387
+ mpfr_bin_ieee754_flavor<T>::min(mpfr_bin_ieee754_flavor<T>::representation_dec const& x,
4388
+ mpfr_bin_ieee754_flavor<T>::representation_dec const& y)
4389
+ {
4390
+ if (!is_valid(x) || !is_valid(y) || is_nai(x) || is_nai(y))
4391
+ return nai();
4392
+
4393
+ // compute bare result
4394
+ representation bare = min(x.first, y.first);
4395
+
4396
+ // compute decoration
4397
+ p1788::decoration::decoration dec = std::min(
4398
+ std::min(x.second, y.second),
4399
+ is_empty(bare) ? p1788::decoration::decoration::trv :
4400
+ is_common_interval(bare) ? p1788::decoration::decoration::com :
4401
+ p1788::decoration::decoration::dac);
4402
+ return representation_dec(bare, dec);
4403
+ }
4404
+
4405
+ // min ( decorated interval ) mixed type
4406
+ template<typename T>
4407
+ template<typename T1, typename T2>
4408
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
4409
+ mpfr_bin_ieee754_flavor<T>::min(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T1> const& x,
4410
+ mpfr_bin_ieee754_flavor<T>::representation_dec_type<T2> const& y)
4411
+ {
4412
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
4413
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
4414
+
4415
+ if (!mpfr_bin_ieee754_flavor<T1>::is_valid(x) || !mpfr_bin_ieee754_flavor<T2>::is_valid(y)
4416
+ || mpfr_bin_ieee754_flavor<T1>::is_nai(x) || mpfr_bin_ieee754_flavor<T2>::is_nai(y))
4417
+ return nai();
4418
+
4419
+ // determine max. precision
4420
+ typedef typename p1788::util::max_precision_type<T,T1,T2>::type T_MAX;
4421
+
4422
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
4423
+ // Error free for floating point inf-sup intervals due to outward rounding
4424
+ return convert_hull(
4425
+ mpfr_bin_ieee754_flavor<T_MAX>::min(
4426
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x),
4427
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(y)
4428
+ )
4429
+ );
4430
+ }
4431
+
4432
+
4433
+
4434
+ // max
4435
+
4436
+ // max ( bare interval )
4437
+ template<typename T>
4438
+ typename mpfr_bin_ieee754_flavor<T>::representation
4439
+ mpfr_bin_ieee754_flavor<T>::max(mpfr_bin_ieee754_flavor<T>::representation const& x,
4440
+ mpfr_bin_ieee754_flavor<T>::representation const& y)
4441
+ {
4442
+ if (!is_valid(x) || !is_valid(y) || is_empty(x) || is_empty(y))
4443
+ return empty();
4444
+
4445
+ return representation(std::max(x.first, y.first), std::max(x.second, y.second));
4446
+ }
4447
+
4448
+ // max ( bare interval ) mixed type
4449
+ template<typename T>
4450
+ template<typename T1, typename T2>
4451
+ typename mpfr_bin_ieee754_flavor<T>::representation
4452
+ mpfr_bin_ieee754_flavor<T>::max(mpfr_bin_ieee754_flavor<T>::representation_type<T1> const& x,
4453
+ mpfr_bin_ieee754_flavor<T>::representation_type<T2> const& y)
4454
+ {
4455
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
4456
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
4457
+
4458
+ if (!mpfr_bin_ieee754_flavor<T1>::is_valid(x) || !mpfr_bin_ieee754_flavor<T2>::is_valid(y))
4459
+ return empty();
4460
+
4461
+ // determine max. precision
4462
+ typedef typename p1788::util::max_precision_type<T,T1,T2>::type T_MAX;
4463
+
4464
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
4465
+ // Error free for floating point inf-sup intervals due to outward rounding
4466
+ return convert_hull(
4467
+ mpfr_bin_ieee754_flavor<T_MAX>::max(
4468
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x),
4469
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(y)
4470
+ )
4471
+ );
4472
+ }
4473
+
4474
+
4475
+ // max ( decorated interval )
4476
+ template<typename T>
4477
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
4478
+ mpfr_bin_ieee754_flavor<T>::max(mpfr_bin_ieee754_flavor<T>::representation_dec const& x,
4479
+ mpfr_bin_ieee754_flavor<T>::representation_dec const& y)
4480
+ {
4481
+ if (!is_valid(x) || !is_valid(y) || is_nai(x) || is_nai(y))
4482
+ return nai();
4483
+
4484
+ // compute bare result
4485
+ representation bare = max(x.first, y.first);
4486
+
4487
+ // compute decoration
4488
+ p1788::decoration::decoration dec = std::min(
4489
+ std::min(x.second, y.second),
4490
+ is_empty(bare) ? p1788::decoration::decoration::trv :
4491
+ is_common_interval(bare) ? p1788::decoration::decoration::com :
4492
+ p1788::decoration::decoration::dac);
4493
+ return representation_dec(bare, dec);
4494
+ }
4495
+
4496
+ // max ( decorated interval ) mixed type
4497
+ template<typename T>
4498
+ template<typename T1, typename T2>
4499
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
4500
+ mpfr_bin_ieee754_flavor<T>::max(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T1> const& x,
4501
+ mpfr_bin_ieee754_flavor<T>::representation_dec_type<T2> const& y)
4502
+ {
4503
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
4504
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
4505
+
4506
+ if (!mpfr_bin_ieee754_flavor<T1>::is_valid(x) || !mpfr_bin_ieee754_flavor<T2>::is_valid(y)
4507
+ || mpfr_bin_ieee754_flavor<T1>::is_nai(x) || mpfr_bin_ieee754_flavor<T2>::is_nai(y))
4508
+ return nai();
4509
+
4510
+ // determine max. precision
4511
+ typedef typename p1788::util::max_precision_type<T,T1,T2>::type T_MAX;
4512
+
4513
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
4514
+ // Error free for floating point inf-sup intervals due to outward rounding
4515
+ return convert_hull(
4516
+ mpfr_bin_ieee754_flavor<T_MAX>::max(
4517
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x),
4518
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(y)
4519
+ )
4520
+ );
4521
+ }
4522
+
4523
+
4524
+ } // namespace setbased
4525
+
4526
+ } // namespace infsup
4527
+
4528
+ } // namespace flavor
4529
+
4530
+ } // namespace p1788
4531
+
4532
+
4533
+ #endif // LIBIEEEP1788_P1788_FLAVOR_INFSUP_SETBASED_MPFR_BIN_IEEE754_FLAVOR_ELEM_FUNC_IMPL_HPP