multiprecision.hpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  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. #ifndef BOOST_REMEZ_MULTIPRECISION_HPP
  6. #define BOOST_REMEZ_MULTIPRECISION_HPP
  7. #include <boost/multiprecision/cpp_bin_float.hpp>
  8. #ifdef USE_NTL
  9. #include <boost/math/bindings/rr.hpp>
  10. namespace std {
  11. using boost::math::ntl::pow;
  12. } // workaround for spirit parser.
  13. typedef boost::math::ntl::RR mp_type;
  14. inline void set_working_precision(int n)
  15. {
  16. NTL::RR::SetPrecision(working_precision);
  17. }
  18. inline int get_working_precision()
  19. {
  20. return mp_type::precision(working_precision);
  21. }
  22. inline void set_output_precision(int n)
  23. {
  24. NTL::RR::SetOutputPrecision(n);
  25. }
  26. inline mp_type round_to_precision(mp_type m, int bits)
  27. {
  28. return NTL::RoundToPrecision(m.value(), bits);
  29. }
  30. namespace boost {
  31. namespace math {
  32. namespace tools {
  33. template <>
  34. inline boost::multiprecision::cpp_bin_float_double_extended real_cast<boost::multiprecision::cpp_bin_float_double_extended, mp_type>(mp_type val)
  35. {
  36. unsigned p = NTL::RR::OutputPrecision();
  37. NTL::RR::SetOutputPrecision(20);
  38. boost::multiprecision::cpp_bin_float_double_extended r = boost::lexical_cast<boost::multiprecision::cpp_bin_float_double_extended>(val);
  39. NTL::RR::SetOutputPrecision(p);
  40. return r;
  41. }
  42. template <>
  43. inline boost::multiprecision::cpp_bin_float_quad real_cast<boost::multiprecision::cpp_bin_float_quad, mp_type>(mp_type val)
  44. {
  45. unsigned p = NTL::RR::OutputPrecision();
  46. NTL::RR::SetOutputPrecision(35);
  47. boost::multiprecision::cpp_bin_float_quad r = boost::lexical_cast<boost::multiprecision::cpp_bin_float_quad>(val);
  48. NTL::RR::SetOutputPrecision(p);
  49. return r;
  50. }
  51. }
  52. }
  53. }
  54. #elif defined(USE_CPP_BIN_FLOAT_100)
  55. #include <boost/multiprecision/cpp_bin_float.hpp>
  56. typedef boost::multiprecision::cpp_bin_float_100 mp_type;
  57. inline void set_working_precision(int n)
  58. {
  59. }
  60. inline void set_output_precision(int n)
  61. {
  62. std::cout << std::setprecision(n);
  63. std::cerr << std::setprecision(n);
  64. }
  65. inline mp_type round_to_precision(mp_type m, int bits)
  66. {
  67. int i;
  68. mp_type f = frexp(m, &i);
  69. f = ldexp(f, bits);
  70. i -= bits;
  71. f = floor(f);
  72. return ldexp(f, i);
  73. }
  74. inline int get_working_precision()
  75. {
  76. return std::numeric_limits<mp_type>::digits;
  77. }
  78. namespace boost {
  79. namespace math {
  80. namespace tools {
  81. template <>
  82. inline boost::multiprecision::cpp_bin_float_double_extended real_cast<boost::multiprecision::cpp_bin_float_double_extended, mp_type>(mp_type val)
  83. {
  84. return boost::multiprecision::cpp_bin_float_double_extended(val);
  85. }
  86. template <>
  87. inline boost::multiprecision::cpp_bin_float_quad real_cast<boost::multiprecision::cpp_bin_float_quad, mp_type>(mp_type val)
  88. {
  89. return boost::multiprecision::cpp_bin_float_quad(val);
  90. }
  91. }
  92. }
  93. }
  94. #elif defined(USE_MPFR_100)
  95. #include <boost/multiprecision/mpfr.hpp>
  96. typedef boost::multiprecision::mpfr_float_100 mp_type;
  97. inline void set_working_precision(int n)
  98. {
  99. }
  100. inline void set_output_precision(int n)
  101. {
  102. std::cout << std::setprecision(n);
  103. std::cerr << std::setprecision(n);
  104. }
  105. inline mp_type round_to_precision(mp_type m, int bits)
  106. {
  107. mpfr_prec_round(m.backend().data(), bits, MPFR_RNDN);
  108. return m;
  109. }
  110. inline int get_working_precision()
  111. {
  112. return std::numeric_limits<mp_type>::digits;
  113. }
  114. namespace boost {
  115. namespace math {
  116. namespace tools {
  117. template <>
  118. inline boost::multiprecision::cpp_bin_float_double_extended real_cast<boost::multiprecision::cpp_bin_float_double_extended, mp_type>(mp_type val)
  119. {
  120. return boost::multiprecision::cpp_bin_float_double_extended(val);
  121. }
  122. template <>
  123. inline boost::multiprecision::cpp_bin_float_quad real_cast<boost::multiprecision::cpp_bin_float_quad, mp_type>(mp_type val)
  124. {
  125. return boost::multiprecision::cpp_bin_float_quad(val);
  126. }
  127. }
  128. }
  129. }
  130. #else
  131. #include <boost/multiprecision/mpfr.hpp>
  132. typedef boost::multiprecision::mpfr_float mp_type;
  133. inline void set_working_precision(int n)
  134. {
  135. boost::multiprecision::mpfr_float::default_precision(boost::multiprecision::detail::digits2_2_10(n));
  136. }
  137. inline void set_output_precision(int n)
  138. {
  139. std::cout << std::setprecision(n);
  140. std::cerr << std::setprecision(n);
  141. }
  142. inline mp_type round_to_precision(mp_type m, int bits)
  143. {
  144. mpfr_prec_round(m.backend().data(), bits, MPFR_RNDN);
  145. return m;
  146. }
  147. inline int get_working_precision()
  148. {
  149. return mp_type::default_precision();
  150. }
  151. namespace boost {
  152. namespace math {
  153. namespace tools {
  154. template <>
  155. inline boost::multiprecision::cpp_bin_float_double_extended real_cast<boost::multiprecision::cpp_bin_float_double_extended, mp_type>(mp_type val)
  156. {
  157. return boost::multiprecision::cpp_bin_float_double_extended(val);
  158. }
  159. template <>
  160. inline boost::multiprecision::cpp_bin_float_quad real_cast<boost::multiprecision::cpp_bin_float_quad, mp_type>(mp_type val)
  161. {
  162. return boost::multiprecision::cpp_bin_float_quad(val);
  163. }
  164. }
  165. }
  166. }
  167. #endif
  168. #endif // BOOST_REMEZ_MULTIPRECISION_HPP