• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //  (C) Copyright John Maddock 2015.
2 //  Use, modification and distribution are subject to the
3 //  Boost Software License, Version 1.0. (See accompanying file
4 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 #ifndef BOOST_REMEZ_MULTIPRECISION_HPP
7 #define BOOST_REMEZ_MULTIPRECISION_HPP
8 
9 #include <boost/multiprecision/cpp_bin_float.hpp>
10 
11 #ifdef USE_NTL
12 #include <boost/math/bindings/rr.hpp>
13 namespace std {
14    using boost::math::ntl::pow;
15 } // workaround for spirit parser.
16 
17 typedef boost::math::ntl::RR mp_type;
18 
set_working_precision(int n)19 inline void set_working_precision(int n)
20 {
21    NTL::RR::SetPrecision(working_precision);
22 }
23 
get_working_precision()24 inline int get_working_precision()
25 {
26    return mp_type::precision(working_precision);
27 }
28 
set_output_precision(int n)29 inline void set_output_precision(int n)
30 {
31    NTL::RR::SetOutputPrecision(n);
32 }
33 
round_to_precision(mp_type m,int bits)34 inline mp_type round_to_precision(mp_type m, int bits)
35 {
36    return NTL::RoundToPrecision(m.value(), bits);
37 }
38 
39 
40 namespace boost {
41    namespace math {
42       namespace tools {
43 
44          template <>
real_cast(mp_type val)45          inline boost::multiprecision::cpp_bin_float_double_extended real_cast<boost::multiprecision::cpp_bin_float_double_extended, mp_type>(mp_type val)
46          {
47             unsigned p = NTL::RR::OutputPrecision();
48             NTL::RR::SetOutputPrecision(20);
49             boost::multiprecision::cpp_bin_float_double_extended r = boost::lexical_cast<boost::multiprecision::cpp_bin_float_double_extended>(val);
50             NTL::RR::SetOutputPrecision(p);
51             return r;
52          }
53          template <>
real_cast(mp_type val)54          inline boost::multiprecision::cpp_bin_float_quad real_cast<boost::multiprecision::cpp_bin_float_quad, mp_type>(mp_type val)
55          {
56             unsigned p = NTL::RR::OutputPrecision();
57             NTL::RR::SetOutputPrecision(35);
58             boost::multiprecision::cpp_bin_float_quad r = boost::lexical_cast<boost::multiprecision::cpp_bin_float_quad>(val);
59             NTL::RR::SetOutputPrecision(p);
60             return r;
61          }
62 
63       }
64    }
65 }
66 
67 #elif defined(USE_CPP_BIN_FLOAT_100)
68 
69 #include <boost/multiprecision/cpp_bin_float.hpp>
70 
71 typedef boost::multiprecision::cpp_bin_float_100 mp_type;
72 
set_working_precision(int n)73 inline void set_working_precision(int n)
74 {
75 }
76 
set_output_precision(int n)77 inline void set_output_precision(int n)
78 {
79    std::cout << std::setprecision(n);
80    std::cerr << std::setprecision(n);
81 }
82 
round_to_precision(mp_type m,int bits)83 inline mp_type round_to_precision(mp_type m, int bits)
84 {
85    int i;
86    mp_type f = frexp(m, &i);
87    f = ldexp(f, bits);
88    i -= bits;
89    f = floor(f);
90    return ldexp(f, i);
91 }
92 
get_working_precision()93 inline int get_working_precision()
94 {
95    return std::numeric_limits<mp_type>::digits;
96 }
97 
98 namespace boost {
99    namespace math {
100       namespace tools {
101 
102          template <>
real_cast(mp_type val)103          inline boost::multiprecision::cpp_bin_float_double_extended real_cast<boost::multiprecision::cpp_bin_float_double_extended, mp_type>(mp_type val)
104          {
105             return boost::multiprecision::cpp_bin_float_double_extended(val);
106          }
107          template <>
real_cast(mp_type val)108          inline boost::multiprecision::cpp_bin_float_quad real_cast<boost::multiprecision::cpp_bin_float_quad, mp_type>(mp_type val)
109          {
110             return boost::multiprecision::cpp_bin_float_quad(val);
111          }
112 
113       }
114    }
115 }
116 
117 
118 #elif defined(USE_MPFR_100)
119 
120 #include <boost/multiprecision/mpfr.hpp>
121 
122 typedef boost::multiprecision::mpfr_float_100 mp_type;
123 
set_working_precision(int n)124 inline void set_working_precision(int n)
125 {
126 }
127 
set_output_precision(int n)128 inline void set_output_precision(int n)
129 {
130    std::cout << std::setprecision(n);
131    std::cerr << std::setprecision(n);
132 }
133 
round_to_precision(mp_type m,int bits)134 inline mp_type round_to_precision(mp_type m, int bits)
135 {
136    mpfr_prec_round(m.backend().data(), bits, MPFR_RNDN);
137    return m;
138 }
139 
get_working_precision()140 inline int get_working_precision()
141 {
142    return std::numeric_limits<mp_type>::digits;
143 }
144 
145 namespace boost {
146    namespace math {
147       namespace tools {
148 
149          template <>
real_cast(mp_type val)150          inline boost::multiprecision::cpp_bin_float_double_extended real_cast<boost::multiprecision::cpp_bin_float_double_extended, mp_type>(mp_type val)
151          {
152             return boost::multiprecision::cpp_bin_float_double_extended(val);
153          }
154          template <>
real_cast(mp_type val)155          inline boost::multiprecision::cpp_bin_float_quad real_cast<boost::multiprecision::cpp_bin_float_quad, mp_type>(mp_type val)
156          {
157             return boost::multiprecision::cpp_bin_float_quad(val);
158          }
159 
160       }
161    }
162 }
163 
164 
165 #else
166 
167 #include <boost/multiprecision/mpfr.hpp>
168 
169 typedef boost::multiprecision::mpfr_float mp_type;
170 
set_working_precision(int n)171 inline void set_working_precision(int n)
172 {
173    boost::multiprecision::mpfr_float::default_precision(boost::multiprecision::detail::digits2_2_10(n));
174 }
175 
set_output_precision(int n)176 inline void set_output_precision(int n)
177 {
178    std::cout << std::setprecision(n);
179    std::cerr << std::setprecision(n);
180 }
181 
round_to_precision(mp_type m,int bits)182 inline mp_type round_to_precision(mp_type m, int bits)
183 {
184    mpfr_prec_round(m.backend().data(), bits, MPFR_RNDN);
185    return m;
186 }
187 
get_working_precision()188 inline int get_working_precision()
189 {
190    return mp_type::default_precision();
191 }
192 
193 namespace boost {
194    namespace math {
195       namespace tools {
196 
197          template <>
real_cast(mp_type val)198          inline boost::multiprecision::cpp_bin_float_double_extended real_cast<boost::multiprecision::cpp_bin_float_double_extended, mp_type>(mp_type val)
199          {
200             return boost::multiprecision::cpp_bin_float_double_extended(val);
201          }
202          template <>
real_cast(mp_type val)203          inline boost::multiprecision::cpp_bin_float_quad real_cast<boost::multiprecision::cpp_bin_float_quad, mp_type>(mp_type val)
204          {
205             return boost::multiprecision::cpp_bin_float_quad(val);
206          }
207 
208       }
209    }
210 }
211 
212 
213 
214 #endif
215 
216 
217 
218 
219 #endif // BOOST_REMEZ_MULTIPRECISION_HPP
220 
221 
222 
223 
224 
225