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.
- checksums.yaml +7 -0
- data/.yardopts +8 -0
- data/AUTHORS +6 -0
- data/LICENSE +201 -0
- data/NOTICE +29 -0
- data/README.md +65 -0
- data/ext/libieeep1788_copy/README +3 -0
- data/ext/libieeep1788_copy/p1788/AUTHORS +16 -0
- data/ext/libieeep1788_copy/p1788/LICENSE +202 -0
- data/ext/libieeep1788_copy/p1788/NOTICE +14 -0
- data/ext/libieeep1788_copy/p1788/decoration/decoration.hpp +265 -0
- data/ext/libieeep1788_copy/p1788/exception/exception.hpp +302 -0
- data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor.hpp +3443 -0
- data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_bool_func_impl.hpp +608 -0
- data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_cancel_func_impl.hpp +229 -0
- data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_class_impl.hpp +526 -0
- data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_elem_func_impl.hpp +4533 -0
- data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_io_impl.hpp +1421 -0
- data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_mul_rev_to_pair_func_impl.hpp +347 -0
- data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_num_func_impl.hpp +655 -0
- data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_rec_bool_func_impl.hpp +146 -0
- data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_rec_overlap_impl.hpp +188 -0
- data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_rev_func_impl.hpp +1674 -0
- data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_set_op_impl.hpp +216 -0
- data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_setup_func_impl.hpp +68 -0
- data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_util_func_impl.hpp +135 -0
- data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_validation_func_impl.hpp +93 -0
- data/ext/libieeep1788_copy/p1788/infsup/base_interval.hpp +1529 -0
- data/ext/libieeep1788_copy/p1788/infsup/base_interval_bool_func_impl.hpp +481 -0
- data/ext/libieeep1788_copy/p1788/infsup/base_interval_cancel_func_impl.hpp +126 -0
- data/ext/libieeep1788_copy/p1788/infsup/base_interval_elem_func_impl.hpp +1581 -0
- data/ext/libieeep1788_copy/p1788/infsup/base_interval_io_impl.hpp +59 -0
- data/ext/libieeep1788_copy/p1788/infsup/base_interval_mul_rev_to_pair_func_impl.hpp +88 -0
- data/ext/libieeep1788_copy/p1788/infsup/base_interval_num_func_impl.hpp +345 -0
- data/ext/libieeep1788_copy/p1788/infsup/base_interval_rec_bool_func_impl.hpp +92 -0
- data/ext/libieeep1788_copy/p1788/infsup/base_interval_rec_overlap_impl.hpp +72 -0
- data/ext/libieeep1788_copy/p1788/infsup/base_interval_rev_func_impl.hpp +656 -0
- data/ext/libieeep1788_copy/p1788/infsup/base_interval_set_op_impl.hpp +126 -0
- data/ext/libieeep1788_copy/p1788/infsup/decorated_interval.hpp +464 -0
- data/ext/libieeep1788_copy/p1788/infsup/forward_declaration.hpp +66 -0
- data/ext/libieeep1788_copy/p1788/infsup/interval.hpp +275 -0
- data/ext/libieeep1788_copy/p1788/io/io_manip.hpp +531 -0
- data/ext/libieeep1788_copy/p1788/overlapping/overlapping.hpp +241 -0
- data/ext/libieeep1788_copy/p1788/p1788.hpp +45 -0
- data/ext/libieeep1788_copy/p1788/reduction/reduction.hpp +341 -0
- data/ext/libieeep1788_copy/p1788/util/io.hpp +63 -0
- data/ext/libieeep1788_copy/p1788/util/mixed_type_traits.hpp +140 -0
- data/ext/libieeep1788_copy/p1788/util/mpfr_util.hpp +77 -0
- data/ext/libieeep1788_copy/p1788/util/mpfr_var.hpp +119 -0
- data/ext/libieeep1788_copy/p1788/util/mpfr_var_impl.hpp +382 -0
- data/ext/libieeep1788_copy/p1788/version.hpp +34 -0
- data/ext/p1788/extconf.rb +49 -0
- data/ext/p1788/p1788.cc +3764 -0
- data/lib/p1788/version.rb +4 -0
- data/lib/p1788.rb +25 -0
- data/p1788.gemspec +72 -0
- metadata +99 -0
@@ -0,0 +1,382 @@
|
|
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_UTIL_MPFR_VAR_IMPL_HPP
|
27
|
+
#define LIBIEEEP1788_P1788_UTIL_MPFR_VAR_IMPL_HPP
|
28
|
+
|
29
|
+
|
30
|
+
namespace p1788
|
31
|
+
{
|
32
|
+
|
33
|
+
namespace util
|
34
|
+
{
|
35
|
+
|
36
|
+
// Trait to return the value as the preferred type
|
37
|
+
template<typename T> class mpfr_get_trait
|
38
|
+
{
|
39
|
+
static_assert(!std::is_same<T,T>::value,
|
40
|
+
"Type is not supported by mpfr_get_trait!");
|
41
|
+
};
|
42
|
+
|
43
|
+
// float
|
44
|
+
template<> class mpfr_get_trait<float>
|
45
|
+
{
|
46
|
+
public:
|
47
|
+
static float apply(mpfr_t& mp, mpfr_rnd_t rnd)
|
48
|
+
{
|
49
|
+
return mpfr_get_flt(mp, rnd);
|
50
|
+
}
|
51
|
+
};
|
52
|
+
|
53
|
+
// double
|
54
|
+
template<> class mpfr_get_trait<double>
|
55
|
+
{
|
56
|
+
public:
|
57
|
+
static double apply(mpfr_t& mp, mpfr_rnd_t rnd)
|
58
|
+
{
|
59
|
+
return mpfr_get_d(mp, rnd);
|
60
|
+
}
|
61
|
+
};
|
62
|
+
|
63
|
+
// long double
|
64
|
+
template<> class mpfr_get_trait<long double>
|
65
|
+
{
|
66
|
+
public:
|
67
|
+
static long double apply(mpfr_t& mp, mpfr_rnd_t rnd)
|
68
|
+
{
|
69
|
+
return mpfr_get_ld(mp, rnd);
|
70
|
+
}
|
71
|
+
};
|
72
|
+
|
73
|
+
// long int
|
74
|
+
template<> class mpfr_get_trait<long int>
|
75
|
+
{
|
76
|
+
public:
|
77
|
+
static long int apply(mpfr_t& mp, mpfr_rnd_t rnd)
|
78
|
+
{
|
79
|
+
return mpfr_get_si(mp, rnd);
|
80
|
+
}
|
81
|
+
};
|
82
|
+
|
83
|
+
// unsigned long int
|
84
|
+
template<> class mpfr_get_trait<unsigned long int>
|
85
|
+
{
|
86
|
+
public:
|
87
|
+
static unsigned long int apply(mpfr_t& mp, mpfr_rnd_t rnd)
|
88
|
+
{
|
89
|
+
return mpfr_get_ui(mp, rnd);
|
90
|
+
}
|
91
|
+
};
|
92
|
+
|
93
|
+
|
94
|
+
// Trait to apply subnormalization if necessary
|
95
|
+
template<bool SUBNORMALIZE>
|
96
|
+
class subnormalization_trait
|
97
|
+
{
|
98
|
+
public:
|
99
|
+
static int apply(mpfr_t&, int t, mpfr_rnd_t)
|
100
|
+
{
|
101
|
+
// Nothing to do
|
102
|
+
return t;
|
103
|
+
}
|
104
|
+
};
|
105
|
+
|
106
|
+
|
107
|
+
// subnormalize
|
108
|
+
template<>
|
109
|
+
class subnormalization_trait<true>
|
110
|
+
{
|
111
|
+
public:
|
112
|
+
static int apply(mpfr_t& x, int t, mpfr_rnd_t rnd)
|
113
|
+
{
|
114
|
+
return mpfr_subnormalize(x, t, rnd);
|
115
|
+
}
|
116
|
+
};
|
117
|
+
|
118
|
+
|
119
|
+
// setup function - initialize the mpfr system
|
120
|
+
template<mpfr_prec_t PREC_, mpfr_exp_t EMIN_, mpfr_exp_t EMAX_, bool SUBNORMALIZE_>
|
121
|
+
void mpfr_var<PREC_,EMIN_,EMAX_,SUBNORMALIZE_>::setup()
|
122
|
+
{
|
123
|
+
mpfr_set_emin(EMIN_);
|
124
|
+
mpfr_set_emax(EMAX_);
|
125
|
+
}
|
126
|
+
|
127
|
+
// clears the mpfr cache
|
128
|
+
template<mpfr_prec_t PREC_, mpfr_exp_t EMIN_, mpfr_exp_t EMAX_, bool SUBNORMALIZE_>
|
129
|
+
void mpfr_var<PREC_,EMIN_,EMAX_,SUBNORMALIZE_>::free_cache()
|
130
|
+
{
|
131
|
+
mpfr_free_cache();
|
132
|
+
}
|
133
|
+
|
134
|
+
// default constructor - value is NaN
|
135
|
+
template<mpfr_prec_t PREC_, mpfr_exp_t EMIN_, mpfr_exp_t EMAX_, bool SUBNORMALIZE_>
|
136
|
+
mpfr_var<PREC_,EMIN_,EMAX_,SUBNORMALIZE_>::mpfr_var()
|
137
|
+
{
|
138
|
+
mpfr_init2(var_, PREC_);
|
139
|
+
}
|
140
|
+
|
141
|
+
// constructor - value is nearest to op in the corresponding rounding direction rnd
|
142
|
+
template<mpfr_prec_t PREC_, mpfr_exp_t EMIN_, mpfr_exp_t EMAX_, bool SUBNORMALIZE_>
|
143
|
+
mpfr_var<PREC_,EMIN_,EMAX_,SUBNORMALIZE_>::mpfr_var(unsigned long int op, mpfr_rnd_t rnd) : mpfr_var()
|
144
|
+
{
|
145
|
+
set(op, rnd);
|
146
|
+
}
|
147
|
+
|
148
|
+
// constructor - value is nearest to op in the corresponding rounding direction rnd
|
149
|
+
template<mpfr_prec_t PREC_, mpfr_exp_t EMIN_, mpfr_exp_t EMAX_, bool SUBNORMALIZE_>
|
150
|
+
mpfr_var<PREC_,EMIN_,EMAX_,SUBNORMALIZE_>::mpfr_var(long int op, mpfr_rnd_t rnd) : mpfr_var()
|
151
|
+
{
|
152
|
+
set(op, rnd);
|
153
|
+
}
|
154
|
+
|
155
|
+
// constructor - value is nearest to op in the corresponding rounding direction rnd
|
156
|
+
template<mpfr_prec_t PREC_, mpfr_exp_t EMIN_, mpfr_exp_t EMAX_, bool SUBNORMALIZE_>
|
157
|
+
mpfr_var<PREC_,EMIN_,EMAX_,SUBNORMALIZE_>::mpfr_var(float op, mpfr_rnd_t rnd) : mpfr_var()
|
158
|
+
{
|
159
|
+
set(op, rnd);
|
160
|
+
}
|
161
|
+
|
162
|
+
// constructor - value is nearest to op in the corresponding rounding direction rnd
|
163
|
+
template<mpfr_prec_t PREC_, mpfr_exp_t EMIN_, mpfr_exp_t EMAX_, bool SUBNORMALIZE_>
|
164
|
+
mpfr_var<PREC_,EMIN_,EMAX_,SUBNORMALIZE_>::mpfr_var(double op, mpfr_rnd_t rnd) : mpfr_var()
|
165
|
+
{
|
166
|
+
set(op, rnd);
|
167
|
+
}
|
168
|
+
|
169
|
+
// constructor - value is nearest to op in the corresponding rounding direction rnd
|
170
|
+
template<mpfr_prec_t PREC_, mpfr_exp_t EMIN_, mpfr_exp_t EMAX_, bool SUBNORMALIZE_>
|
171
|
+
mpfr_var<PREC_,EMIN_,EMAX_,SUBNORMALIZE_>::mpfr_var(long double op, mpfr_rnd_t rnd) : mpfr_var()
|
172
|
+
{
|
173
|
+
set(op, rnd);
|
174
|
+
}
|
175
|
+
|
176
|
+
// Destructor
|
177
|
+
template<mpfr_prec_t PREC_, mpfr_exp_t EMIN_, mpfr_exp_t EMAX_, bool SUBNORMALIZE_>
|
178
|
+
mpfr_var<PREC_,EMIN_,EMAX_,SUBNORMALIZE_>::~mpfr_var()
|
179
|
+
{
|
180
|
+
mpfr_clear(var_);
|
181
|
+
}
|
182
|
+
|
183
|
+
// setter - value is nearest to op in the corresponding rounding direction rnd
|
184
|
+
template<mpfr_prec_t PREC_, mpfr_exp_t EMIN_, mpfr_exp_t EMAX_, bool SUBNORMALIZE_>
|
185
|
+
void mpfr_var<PREC_,EMIN_,EMAX_,SUBNORMALIZE_>::set(unsigned long int op, mpfr_rnd_t rnd)
|
186
|
+
{
|
187
|
+
subnormalize(mpfr_set_ui(var_, op, rnd), rnd);
|
188
|
+
}
|
189
|
+
|
190
|
+
// setter - value is nearest to op in the corresponding rounding direction rnd
|
191
|
+
template<mpfr_prec_t PREC_, mpfr_exp_t EMIN_, mpfr_exp_t EMAX_, bool SUBNORMALIZE_>
|
192
|
+
void mpfr_var<PREC_,EMIN_,EMAX_,SUBNORMALIZE_>::set(long int op, mpfr_rnd_t rnd)
|
193
|
+
{
|
194
|
+
subnormalize(mpfr_set_si(var_, op, rnd), rnd);
|
195
|
+
}
|
196
|
+
|
197
|
+
// setter - value is nearest to op in the corresponding rounding direction rnd
|
198
|
+
template<mpfr_prec_t PREC_, mpfr_exp_t EMIN_, mpfr_exp_t EMAX_, bool SUBNORMALIZE_>
|
199
|
+
void mpfr_var<PREC_,EMIN_,EMAX_,SUBNORMALIZE_>::set(float op, mpfr_rnd_t rnd)
|
200
|
+
{
|
201
|
+
subnormalize(mpfr_set_flt(var_, op, rnd), rnd);
|
202
|
+
}
|
203
|
+
|
204
|
+
// setter - value is nearest to op in the corresponding rounding direction rnd
|
205
|
+
template<mpfr_prec_t PREC_, mpfr_exp_t EMIN_, mpfr_exp_t EMAX_, bool SUBNORMALIZE_>
|
206
|
+
void mpfr_var<PREC_,EMIN_,EMAX_,SUBNORMALIZE_>::set(double op, mpfr_rnd_t rnd)
|
207
|
+
{
|
208
|
+
subnormalize(mpfr_set_d(var_, op, rnd), rnd);
|
209
|
+
}
|
210
|
+
|
211
|
+
// setter - value is nearest to op in the corresponding rounding direction rnd
|
212
|
+
template<mpfr_prec_t PREC_, mpfr_exp_t EMIN_, mpfr_exp_t EMAX_, bool SUBNORMALIZE_>
|
213
|
+
void mpfr_var<PREC_,EMIN_,EMAX_,SUBNORMALIZE_>::set(long double op, mpfr_rnd_t rnd)
|
214
|
+
{
|
215
|
+
subnormalize(mpfr_set_ld(var_, op, rnd), rnd);
|
216
|
+
}
|
217
|
+
|
218
|
+
// getter - returns the value as the preferred type using the rounding direction rnd
|
219
|
+
template<mpfr_prec_t PREC_, mpfr_exp_t EMIN_, mpfr_exp_t EMAX_, bool SUBNORMALIZE_>
|
220
|
+
template<typename T>
|
221
|
+
T mpfr_var<PREC_,EMIN_,EMAX_,SUBNORMALIZE_>::get(mpfr_rnd_t rnd)
|
222
|
+
{
|
223
|
+
return p1788::util::mpfr_get_trait<T>::apply(var_, rnd);
|
224
|
+
}
|
225
|
+
|
226
|
+
// Returns a string representation
|
227
|
+
// It is possible to specify the output format
|
228
|
+
template<mpfr_prec_t PREC_, mpfr_exp_t EMIN_, mpfr_exp_t EMAX_, bool SUBNORMALIZE_>
|
229
|
+
std::string mpfr_var<PREC_,EMIN_,EMAX_,SUBNORMALIZE_>::get_str(mpfr_rnd_t rnd,
|
230
|
+
p1788::io::number_representation_flags rep,
|
231
|
+
size_t width,
|
232
|
+
size_t precision,
|
233
|
+
p1788::io::text_representation_flags text_rep)
|
234
|
+
{
|
235
|
+
std::string format = width > 0 ? "%" + std::to_string(width) : "%";
|
236
|
+
|
237
|
+
size_t req_string_width = 0;
|
238
|
+
|
239
|
+
switch (rep)
|
240
|
+
{
|
241
|
+
case p1788::io::decimal_representation:
|
242
|
+
format += precision > 0 ? "." + std::to_string(precision) : ".6"; // default precision is 6
|
243
|
+
format += "R*";
|
244
|
+
format += text_rep == p1788::io::upper_case_text_representation ? "F" : "f";
|
245
|
+
|
246
|
+
{
|
247
|
+
// Compute upper bound for required integer digits
|
248
|
+
mpfr_var<PREC_,EMIN_,EMAX_,SUBNORMALIZE_> req_digits;
|
249
|
+
mpfr_abs(req_digits(), var_, MPFR_RNDU);
|
250
|
+
mpfr_log10(req_digits(), req_digits(), MPFR_RNDU);
|
251
|
+
|
252
|
+
req_string_width = 1 // for the sign
|
253
|
+
+ req_digits.template get<unsigned long int>(MPFR_RNDD) + 1 // for the digits
|
254
|
+
+ 3 // for dot
|
255
|
+
+ precision > 0 ? precision : 6; // for the digits
|
256
|
+
|
257
|
+
if (width > req_string_width)
|
258
|
+
req_string_width = width;
|
259
|
+
}
|
260
|
+
break;
|
261
|
+
case p1788::io::scientific_representation:
|
262
|
+
format += precision > 0 ? "." + std::to_string(precision) : ".6"; // default precision is 6
|
263
|
+
format += "R*";
|
264
|
+
format += text_rep == p1788::io::upper_case_text_representation ? "E" : "e";
|
265
|
+
{
|
266
|
+
// Compute upper bound of required exponent digits
|
267
|
+
mpfr_var<PREC_,EMIN_,EMAX_,SUBNORMALIZE_> req_exp(std::max(-EMIN_, EMAX_) + 1, MPFR_RNDU);
|
268
|
+
mpfr_div_d(req_exp(), req_exp(), 3.0, MPFR_RNDU); // 1/3 is an upper bound for log10(2)
|
269
|
+
mpfr_log10(req_exp(), req_exp(), MPFR_RNDU);
|
270
|
+
|
271
|
+
req_string_width = 3 // for the pattern "-1."
|
272
|
+
+ precision > 0 ? precision : 6 // for the digits
|
273
|
+
+ 2 // for the pattern "E+"
|
274
|
+
+ req_exp.template get<unsigned long int>(MPFR_RNDD) + 1; // for exponent digits
|
275
|
+
|
276
|
+
if (width > req_string_width)
|
277
|
+
req_string_width = width;
|
278
|
+
}
|
279
|
+
break;
|
280
|
+
case p1788::io::hex_representation:
|
281
|
+
format += precision > 0 ? "." + std::to_string(precision) : ""; // no precision prints sufficient digits for an exact rep
|
282
|
+
format += "R*";
|
283
|
+
format += text_rep == p1788::io::upper_case_text_representation ? "A" : "a";
|
284
|
+
{
|
285
|
+
// Compute upper bound of required hex digits
|
286
|
+
mpfr_var<PREC_,EMIN_,EMAX_,SUBNORMALIZE_> req_prec(PREC_, MPFR_RNDU);
|
287
|
+
mpfr_div_d(req_prec(), req_prec(), 4.0, MPFR_RNDU); // 4 mantissa bits per hex digit
|
288
|
+
|
289
|
+
// Compute upper bound of required exponent digits
|
290
|
+
mpfr_var<PREC_,EMIN_,EMAX_,SUBNORMALIZE_> req_exp(std::max(-EMIN_, EMAX_) + 1, MPFR_RNDU);
|
291
|
+
mpfr_div_d(req_exp(), req_exp(), 3.0, MPFR_RNDU); // 1/3 is an upper bound for log10(2)
|
292
|
+
mpfr_log10(req_exp(), req_exp(), MPFR_RNDU);
|
293
|
+
|
294
|
+
req_string_width = 5 // for the pattern "-0X1."
|
295
|
+
+ req_prec.template get<unsigned long int>(MPFR_RNDU) + 1 // for the hex digits
|
296
|
+
+ 2 // for the pattern "P+"
|
297
|
+
+ req_exp.template get<unsigned long int>(MPFR_RNDD) + 1; // for exponent digits
|
298
|
+
|
299
|
+
if (width > req_string_width)
|
300
|
+
req_string_width = width;
|
301
|
+
}
|
302
|
+
break;
|
303
|
+
default: // decimal_scientific
|
304
|
+
format += precision > 0 ? "." + std::to_string(precision) : ".6"; // default precision is 6
|
305
|
+
format += "R*";
|
306
|
+
format += text_rep == p1788::io::upper_case_text_representation ? "G" : "g";
|
307
|
+
{
|
308
|
+
// Compute upper bound of required integer digits
|
309
|
+
mpfr_var<PREC_,EMIN_,EMAX_,SUBNORMALIZE_> req_digits;
|
310
|
+
mpfr_abs(req_digits(), var_, MPFR_RNDU);
|
311
|
+
mpfr_log10(req_digits(), req_digits(), MPFR_RNDU);
|
312
|
+
|
313
|
+
// Compute upper bound of required exponent digits
|
314
|
+
mpfr_var<PREC_,EMIN_,EMAX_,SUBNORMALIZE_> req_exp(std::max(-EMIN_, EMAX_) + 1, MPFR_RNDU);
|
315
|
+
mpfr_div_d(req_exp(), req_exp(), 3.0, MPFR_RNDU); // 1/3 is an upper bound for log10(2)
|
316
|
+
mpfr_log10(req_exp(), req_exp(), MPFR_RNDU);
|
317
|
+
|
318
|
+
req_string_width = 1 // for the sign
|
319
|
+
+ req_digits.template get<unsigned long int>(MPFR_RNDD) + 1 // for the digits
|
320
|
+
+ 3 // for dot
|
321
|
+
+ precision > 0 ? precision : 6 // for the digits
|
322
|
+
+ 2 // for the pattern "E+"
|
323
|
+
+ req_exp.template get<unsigned long int>(MPFR_RNDD) + 1; // for exponent digits
|
324
|
+
|
325
|
+
if (width > req_string_width)
|
326
|
+
req_string_width = width;
|
327
|
+
}
|
328
|
+
break;
|
329
|
+
}
|
330
|
+
|
331
|
+
// RAII for char array
|
332
|
+
struct string_buffer
|
333
|
+
{
|
334
|
+
char* data;
|
335
|
+
|
336
|
+
string_buffer(size_t n)
|
337
|
+
{
|
338
|
+
data = new char[n + 1]; // take "\0" into account
|
339
|
+
}
|
340
|
+
|
341
|
+
~string_buffer()
|
342
|
+
{
|
343
|
+
delete[] data;
|
344
|
+
};
|
345
|
+
} buffer(req_string_width);
|
346
|
+
|
347
|
+
// generate string
|
348
|
+
mpfr_sprintf(buffer.data, format.c_str(), rnd, var_ );
|
349
|
+
return buffer.data;
|
350
|
+
}
|
351
|
+
|
352
|
+
// Reference to the underlying mpfr_t
|
353
|
+
template<mpfr_prec_t PREC_, mpfr_exp_t EMIN_, mpfr_exp_t EMAX_, bool SUBNORMALIZE_>
|
354
|
+
mpfr_t& mpfr_var<PREC_,EMIN_,EMAX_,SUBNORMALIZE_>::operator() ()
|
355
|
+
{
|
356
|
+
return var_;
|
357
|
+
}
|
358
|
+
|
359
|
+
template<mpfr_prec_t PREC_, mpfr_exp_t EMIN_, mpfr_exp_t EMAX_, bool SUBNORMALIZE_>
|
360
|
+
mpfr_t const& mpfr_var<PREC_,EMIN_,EMAX_,SUBNORMALIZE_>::operator() () const
|
361
|
+
{
|
362
|
+
return var_;
|
363
|
+
}
|
364
|
+
|
365
|
+
|
366
|
+
// subnormalization of the value
|
367
|
+
template<mpfr_prec_t PREC_, mpfr_exp_t EMIN_, mpfr_exp_t EMAX_, bool SUBNORMALIZE_>
|
368
|
+
int mpfr_var<PREC_,EMIN_,EMAX_,SUBNORMALIZE_>::subnormalize(int t, mpfr_rnd_t rnd)
|
369
|
+
{
|
370
|
+
// use traite to distinguish to only apply subnormalization if necessary
|
371
|
+
return p1788::util::subnormalization_trait<SUBNORMALIZE_>::apply(var_, t, rnd);
|
372
|
+
}
|
373
|
+
|
374
|
+
|
375
|
+
|
376
|
+
|
377
|
+
} // namespace util
|
378
|
+
|
379
|
+
} // namespace p1788
|
380
|
+
|
381
|
+
|
382
|
+
#endif // LIBIEEEP1788_P1788_UTIL_MPFR_VAR_IMPL_HPP
|
@@ -0,0 +1,34 @@
|
|
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_VERSION_HPP
|
27
|
+
#define LIBIEEEP1788_P1788_VERSION_HPP
|
28
|
+
|
29
|
+
#define P1788_VERSION_MAJOR 0
|
30
|
+
#define P1788_VERSION_MINOR 1
|
31
|
+
#define P1788_VERSION_PATCH 5
|
32
|
+
#define P1788_VERSION_STRING "0.1.5"
|
33
|
+
|
34
|
+
#endif // LIBIEEEP1788_P1788_VERSION_HPP
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'mkmf'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
unless have_library('gmp') then
|
5
|
+
abort "-----\nGMP is missing. Please install gmp (eg \'sudo apt install libgmp-dev\').\n-----"
|
6
|
+
end
|
7
|
+
|
8
|
+
unless have_library('mpfr') then
|
9
|
+
abort "-----\nMPFR is missing. Please install mpfr (eg \'sudo apt install libmpfr-dev\').\n-----"
|
10
|
+
end
|
11
|
+
|
12
|
+
unless have_header('p1788/p1788.hpp', nil, '-x c++') then
|
13
|
+
ext_dir = File.absolute_path(File.join('..', '..'), __FILE__)
|
14
|
+
=begin
|
15
|
+
## Retrieve headers from Nehmeier's github repository ##
|
16
|
+
libieeep1788_url = 'https://github.com/nehmeier/libieeep1788'
|
17
|
+
libieeep1788_src = File.join(ext_dir, 'libieeep1788')
|
18
|
+
libieeep1788_build = File.join(libieeep1788_src, 'build')
|
19
|
+
|
20
|
+
unless find_executable('git') then
|
21
|
+
abort "-----\nGit is missing. Please install git (eg \'sudo apt install git\').\n-----"
|
22
|
+
end
|
23
|
+
|
24
|
+
unless find_executable('cmake') then
|
25
|
+
abort "-----\ncmake is missing. Please install cmake (eg \'sudo apt install cmake\').\n-----"
|
26
|
+
end
|
27
|
+
|
28
|
+
unless File.directory?(libieeep1788_src) then
|
29
|
+
cmd = "git clone --depth 1 #{libieeep1788_url} #{libieeep1788_src}"
|
30
|
+
message cmd + "\n"
|
31
|
+
abort("-----\n#{caller[0]}\nCannot clone libieeep1788.\n-----") unless system cmd
|
32
|
+
Dir.mkdir libieeep1788_build
|
33
|
+
Dir.chdir(libieeep1788_build) do
|
34
|
+
cmd = "cmake .."
|
35
|
+
message cmd + "\n"
|
36
|
+
abort("-----\n#{caller[0]}\nCannot cmake libieeep1788.\n-----") unless system cmd
|
37
|
+
FileUtils.cp('p1788/version.hpp', '../p1788/')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
$CXXFLAGS += " -I#{libieeep1788_src} "
|
41
|
+
=end
|
42
|
+
|
43
|
+
## Use the embeded copy of the libieeep1788 headers ##
|
44
|
+
$CXXFLAGS += " -I#{File.join(ext_dir, 'libieeep1788_copy')}"
|
45
|
+
$CXXFLAGS += " -Wno-deprecated-declarations"
|
46
|
+
end
|
47
|
+
|
48
|
+
create_makefile 'p1788/p1788'
|
49
|
+
|