You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2735 lines
78 KiB

  1. /*
  2. Multi-precision real number class. C++ interface for MPFR library.
  3. Project homepage: http://www.holoborodko.com/pavel/
  4. Contact e-mail: pavel@holoborodko.com
  5. Copyright (c) 2008-2012 Pavel Holoborodko
  6. Core Developers:
  7. Pavel Holoborodko, Dmitriy Gubanov, Konstantin Holoborodko.
  8. Contributors:
  9. Brian Gladman, Helmut Jarausch, Fokko Beekhof, Ulrich Mutze,
  10. Heinz van Saanen, Pere Constans, Peter van Hoof, Gael Guennebaud,
  11. Tsai Chia Cheng, Alexei Zubanov.
  12. ****************************************************************************
  13. This library is free software; you can redistribute it and/or
  14. modify it under the terms of the GNU Lesser General Public
  15. License as published by the Free Software Foundation; either
  16. version 2.1 of the License, or (at your option) any later version.
  17. This library is distributed in the hope that it will be useful,
  18. but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  20. Lesser General Public License for more details.
  21. You should have received a copy of the GNU Lesser General Public
  22. License along with this library; if not, write to the Free Software
  23. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  24. ****************************************************************************
  25. Redistribution and use in source and binary forms, with or without
  26. modification, are permitted provided that the following conditions
  27. are met:
  28. 1. Redistributions of source code must retain the above copyright
  29. notice, this list of conditions and the following disclaimer.
  30. 2. Redistributions in binary form must reproduce the above copyright
  31. notice, this list of conditions and the following disclaimer in the
  32. documentation and/or other materials provided with the distribution.
  33. 3. The name of the author may be used to endorse or promote products
  34. derived from this software without specific prior written permission.
  35. THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  36. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  37. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  38. ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  39. FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  40. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  41. OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  42. HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  43. LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  44. OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  45. SUCH DAMAGE.
  46. */
  47. #ifndef __MPREAL_H__
  48. #define __MPREAL_H__
  49. #include <string>
  50. #include <iostream>
  51. #include <sstream>
  52. #include <stdexcept>
  53. #include <cfloat>
  54. #include <cmath>
  55. // Options
  56. #define MPREAL_HAVE_INT64_SUPPORT // int64_t support: available only for MSVC 2010 & GCC
  57. #define MPREAL_HAVE_MSVC_DEBUGVIEW // Enable Debugger Visualizer (valid only for MSVC in "Debug" builds)
  58. // Detect compiler using signatures from http://predef.sourceforge.net/
  59. #if defined(__GNUC__) && defined(__INTEL_COMPILER)
  60. #define IsInf(x) isinf(x) // Intel ICC compiler on Linux
  61. #elif defined(_MSC_VER) // Microsoft Visual C++
  62. #define IsInf(x) (!_finite(x))
  63. #elif defined(__GNUC__)
  64. #define IsInf(x) std::isinf(x) // GNU C/C++
  65. #else
  66. #define IsInf(x) std::isinf(x) // Unknown compiler, just hope for C99 conformance
  67. #endif
  68. #if defined(MPREAL_HAVE_INT64_SUPPORT)
  69. #define MPFR_USE_INTMAX_T // should be defined before mpfr.h
  70. #if defined(_MSC_VER) // <stdint.h> is available only in msvc2010!
  71. #if (_MSC_VER >= 1600)
  72. #include <stdint.h>
  73. #else // MPFR relies on intmax_t which is available only in msvc2010
  74. #undef MPREAL_HAVE_INT64_SUPPORT // Besides, MPFR - MPIR have to be compiled with msvc2010
  75. #undef MPFR_USE_INTMAX_T // Since we cannot detect this, disable x64 by default
  76. // Someone should change this manually if needed.
  77. #endif
  78. #endif
  79. #if defined (__MINGW32__) || defined(__MINGW64__)
  80. #include <stdint.h> // equivalent to msvc2010
  81. #elif defined (__GNUC__)
  82. #if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
  83. #undef MPREAL_HAVE_INT64_SUPPORT // remove all shaman dances for x64 builds since
  84. #undef MPFR_USE_INTMAX_T // GCC already support x64 as of "long int" is 64-bit integer, nothing left to do
  85. #else
  86. #include <stdint.h> // use int64_t, uint64_t otherwise.
  87. #endif
  88. #endif
  89. #endif
  90. #if defined(MPREAL_HAVE_MSVC_DEBUGVIEW) && defined(_MSC_VER) && defined(_DEBUG)
  91. #define MPREAL_MSVC_DEBUGVIEW_CODE DebugView = toString()
  92. #define MPREAL_MSVC_DEBUGVIEW_DATA std::string DebugView
  93. #else
  94. #define MPREAL_MSVC_DEBUGVIEW_CODE
  95. #define MPREAL_MSVC_DEBUGVIEW_DATA
  96. #endif
  97. #include <mpfr.h>
  98. #if (MPFR_VERSION < MPFR_VERSION_NUM(3,0,0))
  99. #include <cstdlib> // needed for random()
  100. #endif
  101. namespace mpfr {
  102. class mpreal {
  103. private:
  104. mpfr_t mp;
  105. public:
  106. static mp_rnd_t default_rnd;
  107. static mp_prec_t default_prec;
  108. static int default_base;
  109. static int double_bits;
  110. public:
  111. // Constructors && type conversion
  112. mpreal();
  113. mpreal(const mpreal& u);
  114. mpreal(const mpfr_t u);
  115. mpreal(const mpf_t u);
  116. mpreal(const mpz_t u, mp_prec_t prec = default_prec, mp_rnd_t mode = default_rnd);
  117. mpreal(const mpq_t u, mp_prec_t prec = default_prec, mp_rnd_t mode = default_rnd);
  118. mpreal(const double u, mp_prec_t prec = default_prec, mp_rnd_t mode = default_rnd);
  119. mpreal(const long double u, mp_prec_t prec = default_prec, mp_rnd_t mode = default_rnd);
  120. mpreal(const unsigned long int u, mp_prec_t prec = default_prec, mp_rnd_t mode = default_rnd);
  121. mpreal(const unsigned int u, mp_prec_t prec = default_prec, mp_rnd_t mode = default_rnd);
  122. mpreal(const long int u, mp_prec_t prec = default_prec, mp_rnd_t mode = default_rnd);
  123. mpreal(const int u, mp_prec_t prec = default_prec, mp_rnd_t mode = default_rnd);
  124. #if defined (MPREAL_HAVE_INT64_SUPPORT)
  125. mpreal(const uint64_t u, mp_prec_t prec = default_prec, mp_rnd_t mode = default_rnd);
  126. mpreal(const int64_t u, mp_prec_t prec = default_prec, mp_rnd_t mode = default_rnd);
  127. #endif
  128. mpreal(const char* s, mp_prec_t prec = default_prec, int base = default_base, mp_rnd_t mode = default_rnd);
  129. mpreal(const std::string& s, mp_prec_t prec = default_prec, int base = default_base, mp_rnd_t mode = default_rnd);
  130. ~mpreal();
  131. // Operations
  132. // =
  133. // +, -, *, /, ++, --, <<, >>
  134. // *=, +=, -=, /=,
  135. // <, >, ==, <=, >=
  136. // =
  137. mpreal& operator=(const mpreal& v);
  138. mpreal& operator=(const mpf_t v);
  139. mpreal& operator=(const mpz_t v);
  140. mpreal& operator=(const mpq_t v);
  141. mpreal& operator=(const long double v);
  142. mpreal& operator=(const double v);
  143. mpreal& operator=(const unsigned long int v);
  144. mpreal& operator=(const unsigned int v);
  145. mpreal& operator=(const long int v);
  146. mpreal& operator=(const int v);
  147. mpreal& operator=(const char* s);
  148. // +
  149. mpreal& operator+=(const mpreal& v);
  150. mpreal& operator+=(const mpf_t v);
  151. mpreal& operator+=(const mpz_t v);
  152. mpreal& operator+=(const mpq_t v);
  153. mpreal& operator+=(const long double u);
  154. mpreal& operator+=(const double u);
  155. mpreal& operator+=(const unsigned long int u);
  156. mpreal& operator+=(const unsigned int u);
  157. mpreal& operator+=(const long int u);
  158. mpreal& operator+=(const int u);
  159. #if defined (MPREAL_HAVE_INT64_SUPPORT)
  160. mpreal& operator+=(const int64_t u);
  161. mpreal& operator+=(const uint64_t u);
  162. mpreal& operator-=(const int64_t u);
  163. mpreal& operator-=(const uint64_t u);
  164. mpreal& operator*=(const int64_t u);
  165. mpreal& operator*=(const uint64_t u);
  166. mpreal& operator/=(const int64_t u);
  167. mpreal& operator/=(const uint64_t u);
  168. #endif
  169. const mpreal operator+() const;
  170. mpreal& operator++ ();
  171. const mpreal operator++ (int);
  172. // -
  173. mpreal& operator-=(const mpreal& v);
  174. mpreal& operator-=(const mpz_t v);
  175. mpreal& operator-=(const mpq_t v);
  176. mpreal& operator-=(const long double u);
  177. mpreal& operator-=(const double u);
  178. mpreal& operator-=(const unsigned long int u);
  179. mpreal& operator-=(const unsigned int u);
  180. mpreal& operator-=(const long int u);
  181. mpreal& operator-=(const int u);
  182. const mpreal operator-() const;
  183. friend const mpreal operator-(const unsigned long int b, const mpreal& a);
  184. friend const mpreal operator-(const unsigned int b, const mpreal& a);
  185. friend const mpreal operator-(const long int b, const mpreal& a);
  186. friend const mpreal operator-(const int b, const mpreal& a);
  187. friend const mpreal operator-(const double b, const mpreal& a);
  188. mpreal& operator-- ();
  189. const mpreal operator-- (int);
  190. // *
  191. mpreal& operator*=(const mpreal& v);
  192. mpreal& operator*=(const mpz_t v);
  193. mpreal& operator*=(const mpq_t v);
  194. mpreal& operator*=(const long double v);
  195. mpreal& operator*=(const double v);
  196. mpreal& operator*=(const unsigned long int v);
  197. mpreal& operator*=(const unsigned int v);
  198. mpreal& operator*=(const long int v);
  199. mpreal& operator*=(const int v);
  200. // /
  201. mpreal& operator/=(const mpreal& v);
  202. mpreal& operator/=(const mpz_t v);
  203. mpreal& operator/=(const mpq_t v);
  204. mpreal& operator/=(const long double v);
  205. mpreal& operator/=(const double v);
  206. mpreal& operator/=(const unsigned long int v);
  207. mpreal& operator/=(const unsigned int v);
  208. mpreal& operator/=(const long int v);
  209. mpreal& operator/=(const int v);
  210. friend const mpreal operator/(const unsigned long int b, const mpreal& a);
  211. friend const mpreal operator/(const unsigned int b, const mpreal& a);
  212. friend const mpreal operator/(const long int b, const mpreal& a);
  213. friend const mpreal operator/(const int b, const mpreal& a);
  214. friend const mpreal operator/(const double b, const mpreal& a);
  215. //<<= Fast Multiplication by 2^u
  216. mpreal& operator<<=(const unsigned long int u);
  217. mpreal& operator<<=(const unsigned int u);
  218. mpreal& operator<<=(const long int u);
  219. mpreal& operator<<=(const int u);
  220. //>>= Fast Division by 2^u
  221. mpreal& operator>>=(const unsigned long int u);
  222. mpreal& operator>>=(const unsigned int u);
  223. mpreal& operator>>=(const long int u);
  224. mpreal& operator>>=(const int u);
  225. // Boolean Operators
  226. friend bool operator > (const mpreal& a, const mpreal& b);
  227. friend bool operator >= (const mpreal& a, const mpreal& b);
  228. friend bool operator < (const mpreal& a, const mpreal& b);
  229. friend bool operator <= (const mpreal& a, const mpreal& b);
  230. friend bool operator == (const mpreal& a, const mpreal& b);
  231. friend bool operator != (const mpreal& a, const mpreal& b);
  232. // Optimized specializations for boolean operators
  233. friend bool operator == (const mpreal& a, const unsigned long int b);
  234. friend bool operator == (const mpreal& a, const unsigned int b);
  235. friend bool operator == (const mpreal& a, const long int b);
  236. friend bool operator == (const mpreal& a, const int b);
  237. friend bool operator == (const mpreal& a, const long double b);
  238. friend bool operator == (const mpreal& a, const double b);
  239. // Type Conversion operators
  240. long toLong() const;
  241. unsigned long toULong() const;
  242. double toDouble() const;
  243. long double toLDouble() const;
  244. #if defined (MPREAL_HAVE_INT64_SUPPORT)
  245. int64_t toInt64() const;
  246. uint64_t toUInt64() const;
  247. #endif
  248. // Get raw pointers
  249. ::mpfr_ptr mpfr_ptr();
  250. ::mpfr_srcptr mpfr_srcptr() const;
  251. // Convert mpreal to string with n significant digits in base b
  252. // n = 0 -> convert with the maximum available digits
  253. std::string toString(int n = 0, int b = default_base, mp_rnd_t mode = default_rnd) const;
  254. #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
  255. std::string toString(const std::string& format) const;
  256. #endif
  257. // Math Functions
  258. friend const mpreal sqr (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  259. friend const mpreal sqrt(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  260. friend const mpreal sqrt(const unsigned long int v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  261. friend const mpreal cbrt(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  262. friend const mpreal root(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode = mpreal::default_rnd);
  263. friend const mpreal pow (const mpreal& a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  264. friend const mpreal pow (const mpreal& a, const mpz_t b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  265. friend const mpreal pow (const mpreal& a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  266. friend const mpreal pow (const mpreal& a, const long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  267. friend const mpreal pow (const unsigned long int a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  268. friend const mpreal pow (const unsigned long int a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  269. friend const mpreal fabs(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  270. friend const mpreal abs(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  271. friend const mpreal dim(const mpreal& a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  272. friend inline const mpreal mul_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode = mpreal::default_rnd);
  273. friend inline const mpreal mul_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode = mpreal::default_rnd);
  274. friend inline const mpreal div_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode = mpreal::default_rnd);
  275. friend inline const mpreal div_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode = mpreal::default_rnd);
  276. friend int cmpabs(const mpreal& a,const mpreal& b);
  277. friend const mpreal log (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  278. friend const mpreal log2 (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  279. friend const mpreal log10(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  280. friend const mpreal exp (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  281. friend const mpreal exp2 (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  282. friend const mpreal exp10(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  283. friend const mpreal log1p(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  284. friend const mpreal expm1(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  285. friend const mpreal cos(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  286. friend const mpreal sin(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  287. friend const mpreal tan(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  288. friend const mpreal sec(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  289. friend const mpreal csc(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  290. friend const mpreal cot(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  291. friend int sin_cos(mpreal& s, mpreal& c, const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  292. friend const mpreal acos (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  293. friend const mpreal asin (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  294. friend const mpreal atan (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  295. friend const mpreal atan2 (const mpreal& y, const mpreal& x, mp_rnd_t rnd_mode = mpreal::default_rnd);
  296. friend const mpreal acot (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  297. friend const mpreal asec (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  298. friend const mpreal acsc (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  299. friend const mpreal cosh (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  300. friend const mpreal sinh (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  301. friend const mpreal tanh (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  302. friend const mpreal sech (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  303. friend const mpreal csch (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  304. friend const mpreal coth (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  305. friend const mpreal acosh (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  306. friend const mpreal asinh (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  307. friend const mpreal atanh (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  308. friend const mpreal acoth (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  309. friend const mpreal asech (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  310. friend const mpreal acsch (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  311. friend const mpreal hypot (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::default_rnd);
  312. friend const mpreal fac_ui (unsigned long int v, mp_prec_t prec = mpreal::default_prec, mp_rnd_t rnd_mode = mpreal::default_rnd);
  313. friend const mpreal eint (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  314. friend const mpreal gamma (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  315. friend const mpreal lngamma (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  316. friend const mpreal lgamma (const mpreal& v, int *signp = 0, mp_rnd_t rnd_mode = mpreal::default_rnd);
  317. friend const mpreal zeta (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  318. friend const mpreal erf (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  319. friend const mpreal erfc (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  320. friend const mpreal besselj0 (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  321. friend const mpreal besselj1 (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  322. friend const mpreal besseljn (long n, const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  323. friend const mpreal bessely0 (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  324. friend const mpreal bessely1 (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  325. friend const mpreal besselyn (long n, const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  326. friend const mpreal fma (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode = mpreal::default_rnd);
  327. friend const mpreal fms (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode = mpreal::default_rnd);
  328. friend const mpreal agm (const mpreal& v1, const mpreal& v2, mp_rnd_t rnd_mode = mpreal::default_rnd);
  329. friend const mpreal sum (const mpreal tab[], unsigned long int n, mp_rnd_t rnd_mode = mpreal::default_rnd);
  330. friend int sgn(const mpreal& v); // -1 or +1
  331. // MPFR 2.4.0 Specifics
  332. #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
  333. friend int sinh_cosh(mpreal& s, mpreal& c, const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  334. friend const mpreal li2(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  335. friend const mpreal fmod (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::default_rnd);
  336. friend const mpreal rec_sqrt(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  337. #endif
  338. // MPFR 3.0.0 Specifics
  339. #if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0))
  340. friend const mpreal digamma(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  341. friend const mpreal ai(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  342. friend const mpreal urandom (gmp_randstate_t& state,mp_rnd_t rnd_mode = mpreal::default_rnd); // use gmp_randinit_default() to init state, gmp_randclear() to clear
  343. friend bool isregular(const mpreal& v);
  344. #endif
  345. // Uniformly distributed random number generation in [0,1] using
  346. // Mersenne-Twister algorithm by default.
  347. // Use parameter to setup seed, e.g.: random((unsigned)time(NULL))
  348. // Check urandom() for more precise control.
  349. friend const mpreal random(unsigned int seed = 0);
  350. // Exponent and mantissa manipulation
  351. friend const mpreal frexp(const mpreal& v, mp_exp_t* exp);
  352. friend const mpreal ldexp(const mpreal& v, mp_exp_t exp);
  353. // Splits mpreal value into fractional and integer parts.
  354. // Returns fractional part and stores integer part in n.
  355. friend const mpreal modf(const mpreal& v, mpreal& n);
  356. // Constants
  357. // don't forget to call mpfr_free_cache() for every thread where you are using const-functions
  358. friend const mpreal const_log2 (mp_prec_t prec = mpreal::default_prec, mp_rnd_t rnd_mode = mpreal::default_rnd);
  359. friend const mpreal const_pi (mp_prec_t prec = mpreal::default_prec, mp_rnd_t rnd_mode = mpreal::default_rnd);
  360. friend const mpreal const_euler (mp_prec_t prec = mpreal::default_prec, mp_rnd_t rnd_mode = mpreal::default_rnd);
  361. friend const mpreal const_catalan (mp_prec_t prec = mpreal::default_prec, mp_rnd_t rnd_mode = mpreal::default_rnd);
  362. // returns +inf iff sign>=0 otherwise -inf
  363. friend const mpreal const_infinity(int sign = 1, mp_prec_t prec = mpreal::default_prec, mp_rnd_t rnd_mode = mpreal::default_rnd);
  364. // Output/ Input
  365. friend std::ostream& operator<<(std::ostream& os, const mpreal& v);
  366. friend std::istream& operator>>(std::istream& is, mpreal& v);
  367. // Integer Related Functions
  368. friend const mpreal rint (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  369. friend const mpreal ceil (const mpreal& v);
  370. friend const mpreal floor(const mpreal& v);
  371. friend const mpreal round(const mpreal& v);
  372. friend const mpreal trunc(const mpreal& v);
  373. friend const mpreal rint_ceil (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  374. friend const mpreal rint_floor(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  375. friend const mpreal rint_round(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  376. friend const mpreal rint_trunc(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  377. friend const mpreal frac (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  378. friend const mpreal remainder (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::default_rnd);
  379. friend const mpreal remquo (long* q, const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::default_rnd);
  380. // Miscellaneous Functions
  381. friend const mpreal nexttoward (const mpreal& x, const mpreal& y);
  382. friend const mpreal nextabove (const mpreal& x);
  383. friend const mpreal nextbelow (const mpreal& x);
  384. // use gmp_randinit_default() to init state, gmp_randclear() to clear
  385. friend const mpreal urandomb (gmp_randstate_t& state);
  386. // MPFR < 2.4.2 Specifics
  387. #if (MPFR_VERSION <= MPFR_VERSION_NUM(2,4,2))
  388. friend const mpreal random2 (mp_size_t size, mp_exp_t exp);
  389. #endif
  390. // Instance Checkers
  391. friend bool isnan (const mpreal& v);
  392. friend bool isinf (const mpreal& v);
  393. friend bool isfinite(const mpreal& v);
  394. friend bool isnum(const mpreal& v);
  395. friend bool iszero(const mpreal& v);
  396. friend bool isint(const mpreal& v);
  397. // Set/Get instance properties
  398. inline mp_prec_t get_prec() const;
  399. inline void set_prec(mp_prec_t prec, mp_rnd_t rnd_mode = default_rnd); // Change precision with rounding mode
  400. // Aliases for get_prec(), set_prec() - needed for compatibility with std::complex<mpreal> interface
  401. inline mpreal& setPrecision(int Precision, mp_rnd_t RoundingMode = (mpfr_get_default_rounding_mode)());
  402. inline int getPrecision() const;
  403. // Set mpreal to +/- inf, NaN, +/-0
  404. mpreal& setInf (int Sign = +1);
  405. mpreal& setNan ();
  406. mpreal& setZero (int Sign = +1);
  407. mpreal& setSign (int Sign, mp_rnd_t RoundingMode = (mpfr_get_default_rounding_mode)());
  408. //Exponent
  409. mp_exp_t get_exp();
  410. int set_exp(mp_exp_t e);
  411. int check_range (int t, mp_rnd_t rnd_mode = default_rnd);
  412. int subnormalize (int t,mp_rnd_t rnd_mode = default_rnd);
  413. // Inexact conversion from float
  414. inline bool fits_in_bits(double x, int n);
  415. // Set/Get global properties
  416. static void set_default_prec(mp_prec_t prec);
  417. static mp_prec_t get_default_prec();
  418. static void set_default_base(int base);
  419. static int get_default_base();
  420. static void set_double_bits(int dbits);
  421. static int get_double_bits();
  422. static void set_default_rnd(mp_rnd_t rnd_mode);
  423. static mp_rnd_t get_default_rnd();
  424. static mp_exp_t get_emin (void);
  425. static mp_exp_t get_emax (void);
  426. static mp_exp_t get_emin_min (void);
  427. static mp_exp_t get_emin_max (void);
  428. static mp_exp_t get_emax_min (void);
  429. static mp_exp_t get_emax_max (void);
  430. static int set_emin (mp_exp_t exp);
  431. static int set_emax (mp_exp_t exp);
  432. // Efficient swapping of two mpreal values
  433. friend void swap(mpreal& x, mpreal& y);
  434. //Min Max - macros is evil. Needed for systems which defines max and min globally as macros (e.g. Windows)
  435. //Hope that globally defined macros use > < operations only
  436. friend const mpreal fmax(const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = default_rnd);
  437. friend const mpreal fmin(const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = default_rnd);
  438. #if defined (MPREAL_HAVE_CUSTOM_MPFR_MALLOC)
  439. private:
  440. // Optimized dynamic memory allocation/(re-)deallocation.
  441. static bool is_custom_malloc;
  442. static void *mpreal_allocate (size_t alloc_size);
  443. static void *mpreal_reallocate (void *ptr, size_t old_size, size_t new_size);
  444. static void mpreal_free (void *ptr, size_t size);
  445. inline static void set_custom_malloc (void);
  446. #endif
  447. private:
  448. // Human friendly Debug Preview in Visual Studio.
  449. // Put one of these lines:
  450. //
  451. // mpfr::mpreal=<DebugView> ; Show value only
  452. // mpfr::mpreal=<DebugView>, <mp[0]._mpfr_prec,u>bits ; Show value & precision
  453. //
  454. // at the beginning of
  455. // [Visual Studio Installation Folder]\Common7\Packages\Debugger\autoexp.dat
  456. MPREAL_MSVC_DEBUGVIEW_DATA
  457. };
  458. //////////////////////////////////////////////////////////////////////////
  459. // Exceptions
  460. class conversion_overflow : public std::exception {
  461. public:
  462. std::string why() { return "inexact conversion from floating point"; }
  463. };
  464. namespace internal{
  465. // Use SFINAE to restrict arithmetic operations instantiation only for numeric types
  466. // This is needed for smooth integration with libraries based on expression templates
  467. template <typename ArgumentType> struct result_type {};
  468. template <> struct result_type<mpreal> {typedef mpreal type;};
  469. template <> struct result_type<mpz_t> {typedef mpreal type;};
  470. template <> struct result_type<mpq_t> {typedef mpreal type;};
  471. template <> struct result_type<long double> {typedef mpreal type;};
  472. template <> struct result_type<double> {typedef mpreal type;};
  473. template <> struct result_type<unsigned long int> {typedef mpreal type;};
  474. template <> struct result_type<unsigned int> {typedef mpreal type;};
  475. template <> struct result_type<long int> {typedef mpreal type;};
  476. template <> struct result_type<int> {typedef mpreal type;};
  477. #if defined (MPREAL_HAVE_INT64_SUPPORT)
  478. template <> struct result_type<int64_t > {typedef mpreal type;};
  479. template <> struct result_type<uint64_t > {typedef mpreal type;};
  480. #endif
  481. }
  482. // + Addition
  483. template <typename Rhs>
  484. inline const typename internal::result_type<Rhs>::type
  485. operator+(const mpreal& lhs, const Rhs& rhs){ return mpreal(lhs) += rhs; }
  486. template <typename Lhs>
  487. inline const typename internal::result_type<Lhs>::type
  488. operator+(const Lhs& lhs, const mpreal& rhs){ return mpreal(rhs) += lhs; }
  489. // - Subtraction
  490. template <typename Rhs>
  491. inline const typename internal::result_type<Rhs>::type
  492. operator-(const mpreal& lhs, const Rhs& rhs){ return mpreal(lhs) -= rhs; }
  493. template <typename Lhs>
  494. inline const typename internal::result_type<Lhs>::type
  495. operator-(const Lhs& lhs, const mpreal& rhs){ return mpreal(lhs) -= rhs; }
  496. // * Multiplication
  497. template <typename Rhs>
  498. inline const typename internal::result_type<Rhs>::type
  499. operator*(const mpreal& lhs, const Rhs& rhs){ return mpreal(lhs) *= rhs; }
  500. template <typename Lhs>
  501. inline const typename internal::result_type<Lhs>::type
  502. operator*(const Lhs& lhs, const mpreal& rhs){ return mpreal(rhs) *= lhs; }
  503. // / Division
  504. template <typename Rhs>
  505. inline const typename internal::result_type<Rhs>::type
  506. operator/(const mpreal& lhs, const Rhs& rhs){ return mpreal(lhs) /= rhs; }
  507. template <typename Lhs>
  508. inline const typename internal::result_type<Lhs>::type
  509. operator/(const Lhs& lhs, const mpreal& rhs){ return mpreal(lhs) /= rhs; }
  510. //////////////////////////////////////////////////////////////////////////
  511. // sqrt
  512. const mpreal sqrt(const unsigned int v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  513. const mpreal sqrt(const long int v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  514. const mpreal sqrt(const int v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  515. const mpreal sqrt(const long double v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  516. const mpreal sqrt(const double v, mp_rnd_t rnd_mode = mpreal::default_rnd);
  517. //////////////////////////////////////////////////////////////////////////
  518. // pow
  519. const mpreal pow(const mpreal& a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  520. const mpreal pow(const mpreal& a, const int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  521. const mpreal pow(const mpreal& a, const long double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  522. const mpreal pow(const mpreal& a, const double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  523. const mpreal pow(const unsigned int a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  524. const mpreal pow(const long int a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  525. const mpreal pow(const int a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  526. const mpreal pow(const long double a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  527. const mpreal pow(const double a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  528. const mpreal pow(const unsigned long int a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  529. const mpreal pow(const unsigned long int a, const long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  530. const mpreal pow(const unsigned long int a, const int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  531. const mpreal pow(const unsigned long int a, const long double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  532. const mpreal pow(const unsigned long int a, const double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  533. const mpreal pow(const unsigned int a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  534. const mpreal pow(const unsigned int a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  535. const mpreal pow(const unsigned int a, const long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  536. const mpreal pow(const unsigned int a, const int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  537. const mpreal pow(const unsigned int a, const long double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  538. const mpreal pow(const unsigned int a, const double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  539. const mpreal pow(const long int a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  540. const mpreal pow(const long int a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  541. const mpreal pow(const long int a, const long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  542. const mpreal pow(const long int a, const int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  543. const mpreal pow(const long int a, const long double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  544. const mpreal pow(const long int a, const double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  545. const mpreal pow(const int a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  546. const mpreal pow(const int a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  547. const mpreal pow(const int a, const long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  548. const mpreal pow(const int a, const int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  549. const mpreal pow(const int a, const long double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  550. const mpreal pow(const int a, const double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  551. const mpreal pow(const long double a, const long double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  552. const mpreal pow(const long double a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  553. const mpreal pow(const long double a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  554. const mpreal pow(const long double a, const long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  555. const mpreal pow(const long double a, const int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  556. const mpreal pow(const double a, const double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  557. const mpreal pow(const double a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  558. const mpreal pow(const double a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  559. const mpreal pow(const double a, const long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  560. const mpreal pow(const double a, const int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
  561. //////////////////////////////////////////////////////////////////////////
  562. // Estimate machine epsilon for the given precision
  563. // Returns smallest eps such that 1.0 + eps != 1.0
  564. inline const mpreal machine_epsilon(mp_prec_t prec = mpreal::get_default_prec());
  565. // Returns the positive distance from abs(x) to the next larger in magnitude floating point number of the same precision as x
  566. inline const mpreal machine_epsilon(const mpreal& x);
  567. inline const mpreal mpreal_min(mp_prec_t prec = mpreal::get_default_prec());
  568. inline const mpreal mpreal_max(mp_prec_t prec = mpreal::get_default_prec());
  569. inline bool isEqualFuzzy(const mpreal& a, const mpreal& b, const mpreal& eps);
  570. inline bool isEqualUlps(const mpreal& a, const mpreal& b, int maxUlps);
  571. //////////////////////////////////////////////////////////////////////////
  572. // Bits - decimal digits relation
  573. // bits = ceil(digits*log[2](10))
  574. // digits = floor(bits*log[10](2))
  575. inline mp_prec_t digits2bits(int d);
  576. inline int bits2digits(mp_prec_t b);
  577. //////////////////////////////////////////////////////////////////////////
  578. // min, max
  579. const mpreal (max)(const mpreal& x, const mpreal& y);
  580. const mpreal (min)(const mpreal& x, const mpreal& y);
  581. //////////////////////////////////////////////////////////////////////////
  582. // Implementation
  583. //////////////////////////////////////////////////////////////////////////
  584. //////////////////////////////////////////////////////////////////////////
  585. // Operators - Assignment
  586. inline mpreal& mpreal::operator=(const mpreal& v)
  587. {
  588. if (this != &v)
  589. {
  590. mpfr_clear(mp);
  591. mpfr_init2(mp,mpfr_get_prec(v.mp));
  592. mpfr_set(mp,v.mp,default_rnd);
  593. MPREAL_MSVC_DEBUGVIEW_CODE;
  594. }
  595. return *this;
  596. }
  597. inline mpreal& mpreal::operator=(const mpf_t v)
  598. {
  599. mpfr_set_f(mp,v,default_rnd);
  600. MPREAL_MSVC_DEBUGVIEW_CODE;
  601. return *this;
  602. }
  603. inline mpreal& mpreal::operator=(const mpz_t v)
  604. {
  605. mpfr_set_z(mp,v,default_rnd);
  606. MPREAL_MSVC_DEBUGVIEW_CODE;
  607. return *this;
  608. }
  609. inline mpreal& mpreal::operator=(const mpq_t v)
  610. {
  611. mpfr_set_q(mp,v,default_rnd);
  612. MPREAL_MSVC_DEBUGVIEW_CODE;
  613. return *this;
  614. }
  615. inline mpreal& mpreal::operator=(const long double v)
  616. {
  617. mpfr_set_ld(mp,v,default_rnd);
  618. MPREAL_MSVC_DEBUGVIEW_CODE;
  619. return *this;
  620. }
  621. inline mpreal& mpreal::operator=(const double v)
  622. {
  623. if(double_bits == -1 || fits_in_bits(v, double_bits))
  624. {
  625. mpfr_set_d(mp,v,default_rnd);
  626. MPREAL_MSVC_DEBUGVIEW_CODE;
  627. }
  628. else
  629. throw conversion_overflow();
  630. return *this;
  631. }
  632. inline mpreal& mpreal::operator=(const unsigned long int v)
  633. {
  634. mpfr_set_ui(mp,v,default_rnd);
  635. MPREAL_MSVC_DEBUGVIEW_CODE;
  636. return *this;
  637. }
  638. inline mpreal& mpreal::operator=(const unsigned int v)
  639. {
  640. mpfr_set_ui(mp,v,default_rnd);
  641. MPREAL_MSVC_DEBUGVIEW_CODE;
  642. return *this;
  643. }
  644. inline mpreal& mpreal::operator=(const long int v)
  645. {
  646. mpfr_set_si(mp,v,default_rnd);
  647. MPREAL_MSVC_DEBUGVIEW_CODE;
  648. return *this;
  649. }
  650. inline mpreal& mpreal::operator=(const int v)
  651. {
  652. mpfr_set_si(mp,v,default_rnd);
  653. MPREAL_MSVC_DEBUGVIEW_CODE;
  654. return *this;
  655. }
  656. //////////////////////////////////////////////////////////////////////////
  657. // + Addition
  658. inline mpreal& mpreal::operator+=(const mpreal& v)
  659. {
  660. mpfr_add(mp,mp,v.mp,default_rnd);
  661. MPREAL_MSVC_DEBUGVIEW_CODE;
  662. return *this;
  663. }
  664. inline mpreal& mpreal::operator+=(const mpf_t u)
  665. {
  666. *this += mpreal(u);
  667. MPREAL_MSVC_DEBUGVIEW_CODE;
  668. return *this;
  669. }
  670. inline mpreal& mpreal::operator+=(const mpz_t u)
  671. {
  672. mpfr_add_z(mp,mp,u,default_rnd);
  673. MPREAL_MSVC_DEBUGVIEW_CODE;
  674. return *this;
  675. }
  676. inline mpreal& mpreal::operator+=(const mpq_t u)
  677. {
  678. mpfr_add_q(mp,mp,u,default_rnd);
  679. MPREAL_MSVC_DEBUGVIEW_CODE;
  680. return *this;
  681. }
  682. inline mpreal& mpreal::operator+= (const long double u)
  683. {
  684. *this += mpreal(u);
  685. MPREAL_MSVC_DEBUGVIEW_CODE;
  686. return *this;
  687. }
  688. inline mpreal& mpreal::operator+= (const double u)
  689. {
  690. #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
  691. mpfr_add_d(mp,mp,u,default_rnd);
  692. #else
  693. *this += mpreal(u);
  694. #endif
  695. MPREAL_MSVC_DEBUGVIEW_CODE;
  696. return *this;
  697. }
  698. inline mpreal& mpreal::operator+=(const unsigned long int u)
  699. {
  700. mpfr_add_ui(mp,mp,u,default_rnd);
  701. MPREAL_MSVC_DEBUGVIEW_CODE;
  702. return *this;
  703. }
  704. inline mpreal& mpreal::operator+=(const unsigned int u)
  705. {
  706. mpfr_add_ui(mp,mp,u,default_rnd);
  707. MPREAL_MSVC_DEBUGVIEW_CODE;
  708. return *this;
  709. }
  710. inline mpreal& mpreal::operator+=(const long int u)
  711. {
  712. mpfr_add_si(mp,mp,u,default_rnd);
  713. MPREAL_MSVC_DEBUGVIEW_CODE;
  714. return *this;
  715. }
  716. inline mpreal& mpreal::operator+=(const int u)
  717. {
  718. mpfr_add_si(mp,mp,u,default_rnd);
  719. MPREAL_MSVC_DEBUGVIEW_CODE;
  720. return *this;
  721. }
  722. #if defined (MPREAL_HAVE_INT64_SUPPORT)
  723. inline mpreal& mpreal::operator+=(const int64_t u){ *this += mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; }
  724. inline mpreal& mpreal::operator+=(const uint64_t u){ *this += mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; }
  725. inline mpreal& mpreal::operator-=(const int64_t u){ *this -= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; }
  726. inline mpreal& mpreal::operator-=(const uint64_t u){ *this -= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; }
  727. inline mpreal& mpreal::operator*=(const int64_t u){ *this *= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; }
  728. inline mpreal& mpreal::operator*=(const uint64_t u){ *this *= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; }
  729. inline mpreal& mpreal::operator/=(const int64_t u){ *this /= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; }
  730. inline mpreal& mpreal::operator/=(const uint64_t u){ *this /= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; }
  731. #endif
  732. inline const mpreal mpreal::operator+()const { return mpreal(*this); }
  733. inline const mpreal operator+(const mpreal& a, const mpreal& b)
  734. {
  735. // prec(a+b) = max(prec(a),prec(b))
  736. if(a.get_prec()>b.get_prec()) return mpreal(a) += b;
  737. else return mpreal(b) += a;
  738. }
  739. inline mpreal& mpreal::operator++()
  740. {
  741. return *this += 1;
  742. }
  743. inline const mpreal mpreal::operator++ (int)
  744. {
  745. mpreal x(*this);
  746. *this += 1;
  747. return x;
  748. }
  749. inline mpreal& mpreal::operator--()
  750. {
  751. return *this -= 1;
  752. }
  753. inline const mpreal mpreal::operator-- (int)
  754. {
  755. mpreal x(*this);
  756. *this -= 1;
  757. return x;
  758. }
  759. //////////////////////////////////////////////////////////////////////////
  760. // - Subtraction
  761. inline mpreal& mpreal::operator-= (const mpreal& v)
  762. {
  763. mpfr_sub(mp,mp,v.mp,default_rnd);
  764. MPREAL_MSVC_DEBUGVIEW_CODE;
  765. return *this;
  766. }
  767. inline mpreal& mpreal::operator-=(const mpz_t v)
  768. {
  769. mpfr_sub_z(mp,mp,v,default_rnd);
  770. MPREAL_MSVC_DEBUGVIEW_CODE;
  771. return *this;
  772. }
  773. inline mpreal& mpreal::operator-=(const mpq_t v)
  774. {
  775. mpfr_sub_q(mp,mp,v,default_rnd);
  776. MPREAL_MSVC_DEBUGVIEW_CODE;
  777. return *this;
  778. }
  779. inline mpreal& mpreal::operator-=(const long double v)
  780. {
  781. *this -= mpreal(v);
  782. MPREAL_MSVC_DEBUGVIEW_CODE;
  783. return *this;
  784. }
  785. inline mpreal& mpreal::operator-=(const double v)
  786. {
  787. #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
  788. mpfr_sub_d(mp,mp,v,default_rnd);
  789. #else
  790. *this -= mpreal(v);
  791. #endif
  792. MPREAL_MSVC_DEBUGVIEW_CODE;
  793. return *this;
  794. }
  795. inline mpreal& mpreal::operator-=(const unsigned long int v)
  796. {
  797. mpfr_sub_ui(mp,mp,v,default_rnd);
  798. MPREAL_MSVC_DEBUGVIEW_CODE;
  799. return *this;
  800. }
  801. inline mpreal& mpreal::operator-=(const unsigned int v)
  802. {
  803. mpfr_sub_ui(mp,mp,v,default_rnd);
  804. MPREAL_MSVC_DEBUGVIEW_CODE;
  805. return *this;
  806. }
  807. inline mpreal& mpreal::operator-=(const long int v)
  808. {
  809. mpfr_sub_si(mp,mp,v,default_rnd);
  810. MPREAL_MSVC_DEBUGVIEW_CODE;
  811. return *this;
  812. }
  813. inline mpreal& mpreal::operator-=(const int v)
  814. {
  815. mpfr_sub_si(mp,mp,v,default_rnd);
  816. MPREAL_MSVC_DEBUGVIEW_CODE;
  817. return *this;
  818. }
  819. inline const mpreal mpreal::operator-()const
  820. {
  821. mpreal u(*this);
  822. mpfr_neg(u.mp,u.mp,default_rnd);
  823. return u;
  824. }
  825. inline const mpreal operator-(const mpreal& a, const mpreal& b)
  826. {
  827. // prec(a-b) = max(prec(a),prec(b))
  828. if(a.getPrecision() >= b.getPrecision())
  829. {
  830. return mpreal(a) -= b;
  831. }else{
  832. mpreal x(a);
  833. x.setPrecision(b.getPrecision());
  834. return x -= b;
  835. }
  836. }
  837. inline const mpreal operator-(const double b, const mpreal& a)
  838. {
  839. #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
  840. mpreal x(a);
  841. mpfr_d_sub(x.mp,b,a.mp,mpreal::default_rnd);
  842. return x;
  843. #else
  844. return mpreal(b) -= a;
  845. #endif
  846. }
  847. inline const mpreal operator-(const unsigned long int b, const mpreal& a)
  848. {
  849. mpreal x(a);
  850. mpfr_ui_sub(x.mp,b,a.mp,mpreal::default_rnd);
  851. return x;
  852. }
  853. inline const mpreal operator-(const unsigned int b, const mpreal& a)
  854. {
  855. mpreal x(a);
  856. mpfr_ui_sub(x.mp,b,a.mp,mpreal::default_rnd);
  857. return x;
  858. }
  859. inline const mpreal operator-(const long int b, const mpreal& a)
  860. {
  861. mpreal x(a);
  862. mpfr_si_sub(x.mp,b,a.mp,mpreal::default_rnd);
  863. return x;
  864. }
  865. inline const mpreal operator-(const int b, const mpreal& a)
  866. {
  867. mpreal x(a);
  868. mpfr_si_sub(x.mp,b,a.mp,mpreal::default_rnd);
  869. return x;
  870. }
  871. //////////////////////////////////////////////////////////////////////////
  872. // * Multiplication
  873. inline mpreal& mpreal::operator*= (const mpreal& v)
  874. {
  875. mpfr_mul(mp,mp,v.mp,default_rnd);
  876. MPREAL_MSVC_DEBUGVIEW_CODE;
  877. return *this;
  878. }
  879. inline mpreal& mpreal::operator*=(const mpz_t v)
  880. {
  881. mpfr_mul_z(mp,mp,v,default_rnd);
  882. MPREAL_MSVC_DEBUGVIEW_CODE;
  883. return *this;
  884. }
  885. inline mpreal& mpreal::operator*=(const mpq_t v)
  886. {
  887. mpfr_mul_q(mp,mp,v,default_rnd);
  888. MPREAL_MSVC_DEBUGVIEW_CODE;
  889. return *this;
  890. }
  891. inline mpreal& mpreal::operator*=(const long double v)
  892. {
  893. *this *= mpreal(v);
  894. MPREAL_MSVC_DEBUGVIEW_CODE;
  895. return *this;
  896. }
  897. inline mpreal& mpreal::operator*=(const double v)
  898. {
  899. #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
  900. mpfr_mul_d(mp,mp,v,default_rnd);
  901. #else
  902. *this *= mpreal(v);
  903. #endif
  904. MPREAL_MSVC_DEBUGVIEW_CODE;
  905. return *this;
  906. }
  907. inline mpreal& mpreal::operator*=(const unsigned long int v)
  908. {
  909. mpfr_mul_ui(mp,mp,v,default_rnd);
  910. MPREAL_MSVC_DEBUGVIEW_CODE;
  911. return *this;
  912. }
  913. inline mpreal& mpreal::operator*=(const unsigned int v)
  914. {
  915. mpfr_mul_ui(mp,mp,v,default_rnd);
  916. MPREAL_MSVC_DEBUGVIEW_CODE;
  917. return *this;
  918. }
  919. inline mpreal& mpreal::operator*=(const long int v)
  920. {
  921. mpfr_mul_si(mp,mp,v,default_rnd);
  922. MPREAL_MSVC_DEBUGVIEW_CODE;
  923. return *this;
  924. }
  925. inline mpreal& mpreal::operator*=(const int v)
  926. {
  927. mpfr_mul_si(mp,mp,v,default_rnd);
  928. MPREAL_MSVC_DEBUGVIEW_CODE;
  929. return *this;
  930. }
  931. inline const mpreal operator*(const mpreal& a, const mpreal& b)
  932. {
  933. // prec(a*b) = max(prec(a),prec(b))
  934. if(a.getPrecision() >= b.getPrecision()) return mpreal(a) *= b;
  935. else return mpreal(b) *= a;
  936. }
  937. //////////////////////////////////////////////////////////////////////////
  938. // / Division
  939. inline mpreal& mpreal::operator/=(const mpreal& v)
  940. {
  941. mpfr_div(mp,mp,v.mp,default_rnd);
  942. MPREAL_MSVC_DEBUGVIEW_CODE;
  943. return *this;
  944. }
  945. inline mpreal& mpreal::operator/=(const mpz_t v)
  946. {
  947. mpfr_div_z(mp,mp,v,default_rnd);
  948. MPREAL_MSVC_DEBUGVIEW_CODE;
  949. return *this;
  950. }
  951. inline mpreal& mpreal::operator/=(const mpq_t v)
  952. {
  953. mpfr_div_q(mp,mp,v,default_rnd);
  954. MPREAL_MSVC_DEBUGVIEW_CODE;
  955. return *this;
  956. }
  957. inline mpreal& mpreal::operator/=(const long double v)
  958. {
  959. *this /= mpreal(v);
  960. MPREAL_MSVC_DEBUGVIEW_CODE;
  961. return *this;
  962. }
  963. inline mpreal& mpreal::operator/=(const double v)
  964. {
  965. #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
  966. mpfr_div_d(mp,mp,v,default_rnd);
  967. #else
  968. *this /= mpreal(v);
  969. #endif
  970. MPREAL_MSVC_DEBUGVIEW_CODE;
  971. return *this;
  972. }
  973. inline mpreal& mpreal::operator/=(const unsigned long int v)
  974. {
  975. mpfr_div_ui(mp,mp,v,default_rnd);
  976. MPREAL_MSVC_DEBUGVIEW_CODE;
  977. return *this;
  978. }
  979. inline mpreal& mpreal::operator/=(const unsigned int v)
  980. {
  981. mpfr_div_ui(mp,mp,v,default_rnd);
  982. MPREAL_MSVC_DEBUGVIEW_CODE;
  983. return *this;
  984. }
  985. inline mpreal& mpreal::operator/=(const long int v)
  986. {
  987. mpfr_div_si(mp,mp,v,default_rnd);
  988. MPREAL_MSVC_DEBUGVIEW_CODE;
  989. return *this;
  990. }
  991. inline mpreal& mpreal::operator/=(const int v)
  992. {
  993. mpfr_div_si(mp,mp,v,default_rnd);
  994. MPREAL_MSVC_DEBUGVIEW_CODE;
  995. return *this;
  996. }
  997. inline const mpreal operator/(const mpreal& a, const mpreal& b)
  998. {
  999. // prec(a/b) = max(prec(a),prec(b))
  1000. if(a.getPrecision() >= b.getPrecision())
  1001. {
  1002. return mpreal(a) /= b;
  1003. }else{
  1004. mpreal x(a);
  1005. x.setPrecision(b.getPrecision());
  1006. return x /= b;
  1007. }
  1008. }
  1009. inline const mpreal operator/(const unsigned long int b, const mpreal& a)
  1010. {
  1011. mpreal x(a);
  1012. mpfr_ui_div(x.mp,b,a.mp,mpreal::default_rnd);
  1013. return x;
  1014. }
  1015. inline const mpreal operator/(const unsigned int b, const mpreal& a)
  1016. {
  1017. mpreal x(a);
  1018. mpfr_ui_div(x.mp,b,a.mp,mpreal::default_rnd);
  1019. return x;
  1020. }
  1021. inline const mpreal operator/(const long int b, const mpreal& a)
  1022. {
  1023. mpreal x(a);
  1024. mpfr_si_div(x.mp,b,a.mp,mpreal::default_rnd);
  1025. return x;
  1026. }
  1027. inline const mpreal operator/(const int b, const mpreal& a)
  1028. {
  1029. mpreal x(a);
  1030. mpfr_si_div(x.mp,b,a.mp,mpreal::default_rnd);
  1031. return x;
  1032. }
  1033. inline const mpreal operator/(const double b, const mpreal& a)
  1034. {
  1035. #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
  1036. mpreal x(a);
  1037. mpfr_d_div(x.mp,b,a.mp,mpreal::default_rnd);
  1038. return x;
  1039. #else
  1040. return mpreal(b) /= a;
  1041. #endif
  1042. }
  1043. //////////////////////////////////////////////////////////////////////////
  1044. // Shifts operators - Multiplication/Division by power of 2
  1045. inline mpreal& mpreal::operator<<=(const unsigned long int u)
  1046. {
  1047. mpfr_mul_2ui(mp,mp,u,default_rnd);
  1048. MPREAL_MSVC_DEBUGVIEW_CODE;
  1049. return *this;
  1050. }
  1051. inline mpreal& mpreal::operator<<=(const unsigned int u)
  1052. {
  1053. mpfr_mul_2ui(mp,mp,static_cast<unsigned long int>(u),default_rnd);
  1054. MPREAL_MSVC_DEBUGVIEW_CODE;
  1055. return *this;
  1056. }
  1057. inline mpreal& mpreal::operator<<=(const long int u)
  1058. {
  1059. mpfr_mul_2si(mp,mp,u,default_rnd);
  1060. MPREAL_MSVC_DEBUGVIEW_CODE;
  1061. return *this;
  1062. }
  1063. inline mpreal& mpreal::operator<<=(const int u)
  1064. {
  1065. mpfr_mul_2si(mp,mp,static_cast<long int>(u),default_rnd);
  1066. MPREAL_MSVC_DEBUGVIEW_CODE;
  1067. return *this;
  1068. }
  1069. inline mpreal& mpreal::operator>>=(const unsigned long int u)
  1070. {
  1071. mpfr_div_2ui(mp,mp,u,default_rnd);
  1072. MPREAL_MSVC_DEBUGVIEW_CODE;
  1073. return *this;
  1074. }
  1075. inline mpreal& mpreal::operator>>=(const unsigned int u)
  1076. {
  1077. mpfr_div_2ui(mp,mp,static_cast<unsigned long int>(u),default_rnd);
  1078. MPREAL_MSVC_DEBUGVIEW_CODE;
  1079. return *this;
  1080. }
  1081. inline mpreal& mpreal::operator>>=(const long int u)
  1082. {
  1083. mpfr_div_2si(mp,mp,u,default_rnd);
  1084. MPREAL_MSVC_DEBUGVIEW_CODE;
  1085. return *this;
  1086. }
  1087. inline mpreal& mpreal::operator>>=(const int u)
  1088. {
  1089. mpfr_div_2si(mp,mp,static_cast<long int>(u),default_rnd);
  1090. MPREAL_MSVC_DEBUGVIEW_CODE;
  1091. return *this;
  1092. }
  1093. inline const mpreal operator<<(const mpreal& v, const unsigned long int k)
  1094. {
  1095. return mul_2ui(v,k);
  1096. }
  1097. inline const mpreal operator<<(const mpreal& v, const unsigned int k)
  1098. {
  1099. return mul_2ui(v,static_cast<unsigned long int>(k));
  1100. }
  1101. inline const mpreal operator<<(const mpreal& v, const long int k)
  1102. {
  1103. return mul_2si(v,k);
  1104. }
  1105. inline const mpreal operator<<(const mpreal& v, const int k)
  1106. {
  1107. return mul_2si(v,static_cast<long int>(k));
  1108. }
  1109. inline const mpreal operator>>(const mpreal& v, const unsigned long int k)
  1110. {
  1111. return div_2ui(v,k);
  1112. }
  1113. inline const mpreal operator>>(const mpreal& v, const long int k)
  1114. {
  1115. return div_2si(v,k);
  1116. }
  1117. inline const mpreal operator>>(const mpreal& v, const unsigned int k)
  1118. {
  1119. return div_2ui(v,static_cast<unsigned long int>(k));
  1120. }
  1121. inline const mpreal operator>>(const mpreal& v, const int k)
  1122. {
  1123. return div_2si(v,static_cast<long int>(k));
  1124. }
  1125. // mul_2ui
  1126. inline const mpreal mul_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode)
  1127. {
  1128. mpreal x(v);
  1129. mpfr_mul_2ui(x.mp,v.mp,k,rnd_mode);
  1130. return x;
  1131. }
  1132. // mul_2si
  1133. inline const mpreal mul_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode)
  1134. {
  1135. mpreal x(v);
  1136. mpfr_mul_2si(x.mp,v.mp,k,rnd_mode);
  1137. return x;
  1138. }
  1139. inline const mpreal div_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode)
  1140. {
  1141. mpreal x(v);
  1142. mpfr_div_2ui(x.mp,v.mp,k,rnd_mode);
  1143. return x;
  1144. }
  1145. inline const mpreal div_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode)
  1146. {
  1147. mpreal x(v);
  1148. mpfr_div_2si(x.mp,v.mp,k,rnd_mode);
  1149. return x;
  1150. }
  1151. //////////////////////////////////////////////////////////////////////////
  1152. //Boolean operators
  1153. inline bool operator > (const mpreal& a, const mpreal& b){ return (mpfr_greater_p(a.mp,b.mp) !=0); }
  1154. inline bool operator >= (const mpreal& a, const mpreal& b){ return (mpfr_greaterequal_p(a.mp,b.mp) !=0); }
  1155. inline bool operator < (const mpreal& a, const mpreal& b){ return (mpfr_less_p(a.mp,b.mp) !=0); }
  1156. inline bool operator <= (const mpreal& a, const mpreal& b){ return (mpfr_lessequal_p(a.mp,b.mp) !=0); }
  1157. inline bool operator == (const mpreal& a, const mpreal& b){ return (mpfr_equal_p(a.mp,b.mp) !=0); }
  1158. inline bool operator != (const mpreal& a, const mpreal& b){ return (mpfr_lessgreater_p(a.mp,b.mp) !=0); }
  1159. inline bool operator == (const mpreal& a, const unsigned long int b ){ return (mpfr_cmp_ui(a.mp,b) == 0); }
  1160. inline bool operator == (const mpreal& a, const unsigned int b ){ return (mpfr_cmp_ui(a.mp,b) == 0); }
  1161. inline bool operator == (const mpreal& a, const long int b ){ return (mpfr_cmp_si(a.mp,b) == 0); }
  1162. inline bool operator == (const mpreal& a, const int b ){ return (mpfr_cmp_si(a.mp,b) == 0); }
  1163. inline bool operator == (const mpreal& a, const long double b ){ return (mpfr_cmp_ld(a.mp,b) == 0); }
  1164. inline bool operator == (const mpreal& a, const double b ){ return (mpfr_cmp_d(a.mp,b) == 0); }
  1165. inline bool isnan (const mpreal& v){ return (mpfr_nan_p(v.mp) != 0); }
  1166. inline bool isinf (const mpreal& v){ return (mpfr_inf_p(v.mp) != 0); }
  1167. inline bool isfinite(const mpreal& v){ return (mpfr_number_p(v.mp) != 0); }
  1168. inline bool iszero (const mpreal& v){ return (mpfr_zero_p(v.mp) != 0); }
  1169. inline bool isint (const mpreal& v){ return (mpfr_integer_p(v.mp) != 0); }
  1170. #if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0))
  1171. inline bool isregular(const mpreal& v){ return (mpfr_regular_p(v.mp));}
  1172. #endif
  1173. //////////////////////////////////////////////////////////////////////////
  1174. // Type Converters
  1175. inline long mpreal::toLong() const { return mpfr_get_si(mp,GMP_RNDZ); }
  1176. inline unsigned long mpreal::toULong() const { return mpfr_get_ui(mp,GMP_RNDZ); }
  1177. inline double mpreal::toDouble() const { return mpfr_get_d(mp,default_rnd); }
  1178. inline long double mpreal::toLDouble() const { return mpfr_get_ld(mp,default_rnd); }
  1179. #if defined (MPREAL_HAVE_INT64_SUPPORT)
  1180. inline int64_t mpreal::toInt64() const{ return mpfr_get_sj(mp,GMP_RNDZ); }
  1181. inline uint64_t mpreal::toUInt64() const{ return mpfr_get_uj(mp,GMP_RNDZ); }
  1182. #endif
  1183. inline ::mpfr_ptr mpreal::mpfr_ptr() { return mp; }
  1184. inline ::mpfr_srcptr mpreal::mpfr_srcptr() const { return const_cast< ::mpfr_srcptr >(mp); }
  1185. //////////////////////////////////////////////////////////////////////////
  1186. // Bits - decimal digits relation
  1187. // bits = ceil(digits*log[2](10))
  1188. // digits = floor(bits*log[10](2))
  1189. inline mp_prec_t digits2bits(int d)
  1190. {
  1191. const double LOG2_10 = 3.3219280948873624;
  1192. d = 10>d?10:d;
  1193. return (mp_prec_t)std::ceil((d)*LOG2_10);
  1194. }
  1195. inline int bits2digits(mp_prec_t b)
  1196. {
  1197. const double LOG10_2 = 0.30102999566398119;
  1198. b = 34>b?34:b;
  1199. return (int)std::floor((b)*LOG10_2);
  1200. }
  1201. //////////////////////////////////////////////////////////////////////////
  1202. // Set/Get number properties
  1203. inline int sgn(const mpreal& v)
  1204. {
  1205. int r = mpfr_signbit(v.mp);
  1206. return (r>0?-1:1);
  1207. }
  1208. inline mpreal& mpreal::setSign(int sign, mp_rnd_t RoundingMode)
  1209. {
  1210. mpfr_setsign(mp,mp,(sign<0?1:0),RoundingMode);
  1211. MPREAL_MSVC_DEBUGVIEW_CODE;
  1212. return *this;
  1213. }
  1214. inline int mpreal::getPrecision() const
  1215. {
  1216. return mpfr_get_prec(mp);
  1217. }
  1218. inline mpreal& mpreal::setPrecision(int Precision, mp_rnd_t RoundingMode)
  1219. {
  1220. mpfr_prec_round(mp,Precision, RoundingMode);
  1221. MPREAL_MSVC_DEBUGVIEW_CODE;
  1222. return *this;
  1223. }
  1224. inline mpreal& mpreal::setInf(int sign)
  1225. {
  1226. mpfr_set_inf(mp,sign);
  1227. MPREAL_MSVC_DEBUGVIEW_CODE;
  1228. return *this;
  1229. }
  1230. inline mpreal& mpreal::setNan()
  1231. {
  1232. mpfr_set_nan(mp);
  1233. MPREAL_MSVC_DEBUGVIEW_CODE;
  1234. return *this;
  1235. }
  1236. inline mpreal& mpreal::setZero(int sign)
  1237. {
  1238. mpfr_set_zero(mp,sign);
  1239. MPREAL_MSVC_DEBUGVIEW_CODE;
  1240. return *this;
  1241. }
  1242. inline mp_prec_t mpreal::get_prec() const
  1243. {
  1244. return mpfr_get_prec(mp);
  1245. }
  1246. inline void mpreal::set_prec(mp_prec_t prec, mp_rnd_t rnd_mode)
  1247. {
  1248. mpfr_prec_round(mp,prec,rnd_mode);
  1249. MPREAL_MSVC_DEBUGVIEW_CODE;
  1250. }
  1251. inline mp_exp_t mpreal::get_exp ()
  1252. {
  1253. return mpfr_get_exp(mp);
  1254. }
  1255. inline int mpreal::set_exp (mp_exp_t e)
  1256. {
  1257. int x = mpfr_set_exp(mp, e);
  1258. MPREAL_MSVC_DEBUGVIEW_CODE;
  1259. return x;
  1260. }
  1261. inline const mpreal frexp(const mpreal& v, mp_exp_t* exp)
  1262. {
  1263. mpreal x(v);
  1264. *exp = x.get_exp();
  1265. x.set_exp(0);
  1266. return x;
  1267. }
  1268. inline const mpreal ldexp(const mpreal& v, mp_exp_t exp)
  1269. {
  1270. mpreal x(v);
  1271. // rounding is not important since we just increasing the exponent
  1272. mpfr_mul_2si(x.mp,x.mp,exp,mpreal::default_rnd);
  1273. return x;
  1274. }
  1275. inline const mpreal machine_epsilon(mp_prec_t prec)
  1276. {
  1277. // the smallest eps such that 1.0+eps != 1.0
  1278. // depends (of cause) on the precision
  1279. return machine_epsilon(mpreal(1,prec));
  1280. }
  1281. inline const mpreal machine_epsilon(const mpreal& x)
  1282. {
  1283. if( x < 0)
  1284. {
  1285. return nextabove(-x)+x;
  1286. }else{
  1287. return nextabove(x)-x;
  1288. }
  1289. }
  1290. inline const mpreal mpreal_min(mp_prec_t prec)
  1291. {
  1292. // min = 1/2*2^emin = 2^(emin-1)
  1293. return mpreal(1,prec) << mpreal::get_emin()-1;
  1294. }
  1295. inline const mpreal mpreal_max(mp_prec_t prec)
  1296. {
  1297. // max = (1-eps)*2^emax, assume eps = 0?,
  1298. // and use emax-1 to prevent value to be +inf
  1299. // max = 2^(emax-1)
  1300. return mpreal(1,prec) << mpreal::get_emax()-1;
  1301. }
  1302. inline bool isEqualUlps(const mpreal& a, const mpreal& b, int maxUlps)
  1303. {
  1304. /*
  1305. maxUlps - a and b can be apart by maxUlps binary numbers.
  1306. */
  1307. return abs(a - b) <= machine_epsilon((max)(abs(a), abs(b))) * maxUlps;
  1308. }
  1309. inline bool isEqualFuzzy(const mpreal& a, const mpreal& b, const mpreal& eps)
  1310. {
  1311. return abs(a - b) <= (min)(abs(a), abs(b)) * eps;
  1312. }
  1313. inline bool isEqualFuzzy(const mpreal& a, const mpreal& b)
  1314. {
  1315. return isEqualFuzzy(a,b,machine_epsilon((std::min)(abs(a), abs(b))));
  1316. }
  1317. inline const mpreal modf(const mpreal& v, mpreal& n)
  1318. {
  1319. mpreal frac(v);
  1320. // rounding is not important since we are using the same number
  1321. mpfr_frac(frac.mp,frac.mp,mpreal::default_rnd);
  1322. mpfr_trunc(n.mp,v.mp);
  1323. return frac;
  1324. }
  1325. inline int mpreal::check_range (int t, mp_rnd_t rnd_mode)
  1326. {
  1327. return mpfr_check_range(mp,t,rnd_mode);
  1328. }
  1329. inline int mpreal::subnormalize (int t,mp_rnd_t rnd_mode)
  1330. {
  1331. int r = mpfr_subnormalize(mp,t,rnd_mode);
  1332. MPREAL_MSVC_DEBUGVIEW_CODE;
  1333. return r;
  1334. }
  1335. inline mp_exp_t mpreal::get_emin (void)
  1336. {
  1337. return mpfr_get_emin();
  1338. }
  1339. inline int mpreal::set_emin (mp_exp_t exp)
  1340. {
  1341. return mpfr_set_emin(exp);
  1342. }
  1343. inline mp_exp_t mpreal::get_emax (void)
  1344. {
  1345. return mpfr_get_emax();
  1346. }
  1347. inline int mpreal::set_emax (mp_exp_t exp)
  1348. {
  1349. return mpfr_set_emax(exp);
  1350. }
  1351. inline mp_exp_t mpreal::get_emin_min (void)
  1352. {
  1353. return mpfr_get_emin_min();
  1354. }
  1355. inline mp_exp_t mpreal::get_emin_max (void)
  1356. {
  1357. return mpfr_get_emin_max();
  1358. }
  1359. inline mp_exp_t mpreal::get_emax_min (void)
  1360. {
  1361. return mpfr_get_emax_min();
  1362. }
  1363. inline mp_exp_t mpreal::get_emax_max (void)
  1364. {
  1365. return mpfr_get_emax_max();
  1366. }
  1367. //////////////////////////////////////////////////////////////////////////
  1368. // Mathematical Functions
  1369. //////////////////////////////////////////////////////////////////////////
  1370. inline const mpreal sqr(const mpreal& v, mp_rnd_t rnd_mode)
  1371. {
  1372. mpreal x(v);
  1373. mpfr_sqr(x.mp,x.mp,rnd_mode);
  1374. return x;
  1375. }
  1376. inline const mpreal sqrt(const mpreal& v, mp_rnd_t rnd_mode)
  1377. {
  1378. mpreal x(v);
  1379. mpfr_sqrt(x.mp,x.mp,rnd_mode);
  1380. return x;
  1381. }
  1382. inline const mpreal sqrt(const unsigned long int v, mp_rnd_t rnd_mode)
  1383. {
  1384. mpreal x;
  1385. mpfr_sqrt_ui(x.mp,v,rnd_mode);
  1386. return x;
  1387. }
  1388. inline const mpreal sqrt(const unsigned int v, mp_rnd_t rnd_mode)
  1389. {
  1390. return sqrt(static_cast<unsigned long int>(v),rnd_mode);
  1391. }
  1392. inline const mpreal sqrt(const long int v, mp_rnd_t rnd_mode)
  1393. {
  1394. if (v>=0) return sqrt(static_cast<unsigned long int>(v),rnd_mode);
  1395. else return mpreal().setNan(); // NaN
  1396. }
  1397. inline const mpreal sqrt(const int v, mp_rnd_t rnd_mode)
  1398. {
  1399. if (v>=0) return sqrt(static_cast<unsigned long int>(v),rnd_mode);
  1400. else return mpreal().setNan(); // NaN
  1401. }
  1402. inline const mpreal sqrt(const long double v, mp_rnd_t rnd_mode)
  1403. {
  1404. return sqrt(mpreal(v),rnd_mode);
  1405. }
  1406. inline const mpreal sqrt(const double v, mp_rnd_t rnd_mode)
  1407. {
  1408. return sqrt(mpreal(v),rnd_mode);
  1409. }
  1410. inline const mpreal cbrt(const mpreal& v, mp_rnd_t rnd_mode)
  1411. {
  1412. mpreal x(v);
  1413. mpfr_cbrt(x.mp,x.mp,rnd_mode);
  1414. return x;
  1415. }
  1416. inline const mpreal root(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode)
  1417. {
  1418. mpreal x(v);
  1419. mpfr_root(x.mp,x.mp,k,rnd_mode);
  1420. return x;
  1421. }
  1422. inline const mpreal fabs(const mpreal& v, mp_rnd_t rnd_mode)
  1423. {
  1424. mpreal x(v);
  1425. mpfr_abs(x.mp,x.mp,rnd_mode);
  1426. return x;
  1427. }
  1428. inline const mpreal abs(const mpreal& v, mp_rnd_t rnd_mode)
  1429. {
  1430. mpreal x(v);
  1431. mpfr_abs(x.mp,x.mp,rnd_mode);
  1432. return x;
  1433. }
  1434. inline const mpreal dim(const mpreal& a, const mpreal& b, mp_rnd_t rnd_mode)
  1435. {
  1436. mpreal x(a);
  1437. mpfr_dim(x.mp,a.mp,b.mp,rnd_mode);
  1438. return x;
  1439. }
  1440. inline int cmpabs(const mpreal& a,const mpreal& b)
  1441. {
  1442. return mpfr_cmpabs(a.mp,b.mp);
  1443. }
  1444. inline const mpreal log (const mpreal& v, mp_rnd_t rnd_mode)
  1445. {
  1446. mpreal x(v);
  1447. mpfr_log(x.mp,v.mp,rnd_mode);
  1448. return x;
  1449. }
  1450. inline const mpreal log2(const mpreal& v, mp_rnd_t rnd_mode)
  1451. {
  1452. mpreal x(v);
  1453. mpfr_log2(x.mp,v.mp,rnd_mode);
  1454. return x;
  1455. }
  1456. inline const mpreal log10(const mpreal& v, mp_rnd_t rnd_mode)
  1457. {
  1458. mpreal x(v);
  1459. mpfr_log10(x.mp,v.mp,rnd_mode);
  1460. return x;
  1461. }
  1462. inline const mpreal exp(const mpreal& v, mp_rnd_t rnd_mode)
  1463. {
  1464. mpreal x(v);
  1465. mpfr_exp(x.mp,v.mp,rnd_mode);
  1466. return x;
  1467. }
  1468. inline const mpreal exp2(const mpreal& v, mp_rnd_t rnd_mode)
  1469. {
  1470. mpreal x(v);
  1471. mpfr_exp2(x.mp,v.mp,rnd_mode);
  1472. return x;
  1473. }
  1474. inline const mpreal exp10(const mpreal& v, mp_rnd_t rnd_mode)
  1475. {
  1476. mpreal x(v);
  1477. mpfr_exp10(x.mp,v.mp,rnd_mode);
  1478. return x;
  1479. }
  1480. inline const mpreal cos(const mpreal& v, mp_rnd_t rnd_mode)
  1481. {
  1482. mpreal x(v);
  1483. mpfr_cos(x.mp,v.mp,rnd_mode);
  1484. return x;
  1485. }
  1486. inline const mpreal sin(const mpreal& v, mp_rnd_t rnd_mode)
  1487. {
  1488. mpreal x(v);
  1489. mpfr_sin(x.mp,v.mp,rnd_mode);
  1490. return x;
  1491. }
  1492. inline const mpreal tan(const mpreal& v, mp_rnd_t rnd_mode)
  1493. {
  1494. mpreal x(v);
  1495. mpfr_tan(x.mp,v.mp,rnd_mode);
  1496. return x;
  1497. }
  1498. inline const mpreal sec(const mpreal& v, mp_rnd_t rnd_mode)
  1499. {
  1500. mpreal x(v);
  1501. mpfr_sec(x.mp,v.mp,rnd_mode);
  1502. return x;
  1503. }
  1504. inline const mpreal csc(const mpreal& v, mp_rnd_t rnd_mode)
  1505. {
  1506. mpreal x(v);
  1507. mpfr_csc(x.mp,v.mp,rnd_mode);
  1508. return x;
  1509. }
  1510. inline const mpreal cot(const mpreal& v, mp_rnd_t rnd_mode)
  1511. {
  1512. mpreal x(v);
  1513. mpfr_cot(x.mp,v.mp,rnd_mode);
  1514. return x;
  1515. }
  1516. inline int sin_cos(mpreal& s, mpreal& c, const mpreal& v, mp_rnd_t rnd_mode)
  1517. {
  1518. return mpfr_sin_cos(s.mp,c.mp,v.mp,rnd_mode);
  1519. }
  1520. inline const mpreal acos (const mpreal& v, mp_rnd_t rnd_mode)
  1521. {
  1522. mpreal x(v);
  1523. mpfr_acos(x.mp,v.mp,rnd_mode);
  1524. return x;
  1525. }
  1526. inline const mpreal asin (const mpreal& v, mp_rnd_t rnd_mode)
  1527. {
  1528. mpreal x(v);
  1529. mpfr_asin(x.mp,v.mp,rnd_mode);
  1530. return x;
  1531. }
  1532. inline const mpreal atan (const mpreal& v, mp_rnd_t rnd_mode)
  1533. {
  1534. mpreal x(v);
  1535. mpfr_atan(x.mp,v.mp,rnd_mode);
  1536. return x;
  1537. }
  1538. inline const mpreal acot (const mpreal& v, mp_rnd_t rnd_mode)
  1539. {
  1540. return atan(1/v, rnd_mode);
  1541. }
  1542. inline const mpreal asec (const mpreal& v, mp_rnd_t rnd_mode)
  1543. {
  1544. return acos(1/v, rnd_mode);
  1545. }
  1546. inline const mpreal acsc (const mpreal& v, mp_rnd_t rnd_mode)
  1547. {
  1548. return asin(1/v, rnd_mode);
  1549. }
  1550. inline const mpreal acoth (const mpreal& v, mp_rnd_t rnd_mode)
  1551. {
  1552. return atanh(1/v, rnd_mode);
  1553. }
  1554. inline const mpreal asech (const mpreal& v, mp_rnd_t rnd_mode)
  1555. {
  1556. return acosh(1/v, rnd_mode);
  1557. }
  1558. inline const mpreal acsch (const mpreal& v, mp_rnd_t rnd_mode)
  1559. {
  1560. return asinh(1/v, rnd_mode);
  1561. }
  1562. inline const mpreal atan2 (const mpreal& y, const mpreal& x, mp_rnd_t rnd_mode)
  1563. {
  1564. mpreal a;
  1565. mp_prec_t yp, xp;
  1566. yp = y.get_prec();
  1567. xp = x.get_prec();
  1568. a.set_prec(yp>xp?yp:xp);
  1569. mpfr_atan2(a.mp, y.mp, x.mp, rnd_mode);
  1570. return a;
  1571. }
  1572. inline const mpreal cosh (const mpreal& v, mp_rnd_t rnd_mode)
  1573. {
  1574. mpreal x(v);
  1575. mpfr_cosh(x.mp,v.mp,rnd_mode);
  1576. return x;
  1577. }
  1578. inline const mpreal sinh (const mpreal& v, mp_rnd_t rnd_mode)
  1579. {
  1580. mpreal x(v);
  1581. mpfr_sinh(x.mp,v.mp,rnd_mode);
  1582. return x;
  1583. }
  1584. inline const mpreal tanh (const mpreal& v, mp_rnd_t rnd_mode)
  1585. {
  1586. mpreal x(v);
  1587. mpfr_tanh(x.mp,v.mp,rnd_mode);
  1588. return x;
  1589. }
  1590. inline const mpreal sech (const mpreal& v, mp_rnd_t rnd_mode)
  1591. {
  1592. mpreal x(v);
  1593. mpfr_sech(x.mp,v.mp,rnd_mode);
  1594. return x;
  1595. }
  1596. inline const mpreal csch (const mpreal& v, mp_rnd_t rnd_mode)
  1597. {
  1598. mpreal x(v);
  1599. mpfr_csch(x.mp,v.mp,rnd_mode);
  1600. return x;
  1601. }
  1602. inline const mpreal coth (const mpreal& v, mp_rnd_t rnd_mode)
  1603. {
  1604. mpreal x(v);
  1605. mpfr_coth(x.mp,v.mp,rnd_mode);
  1606. return x;
  1607. }
  1608. inline const mpreal acosh (const mpreal& v, mp_rnd_t rnd_mode)
  1609. {
  1610. mpreal x(v);
  1611. mpfr_acosh(x.mp,v.mp,rnd_mode);
  1612. return x;
  1613. }
  1614. inline const mpreal asinh (const mpreal& v, mp_rnd_t rnd_mode)
  1615. {
  1616. mpreal x(v);
  1617. mpfr_asinh(x.mp,v.mp,rnd_mode);
  1618. return x;
  1619. }
  1620. inline const mpreal atanh (const mpreal& v, mp_rnd_t rnd_mode)
  1621. {
  1622. mpreal x(v);
  1623. mpfr_atanh(x.mp,v.mp,rnd_mode);
  1624. return x;
  1625. }
  1626. inline const mpreal hypot (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode)
  1627. {
  1628. mpreal a;
  1629. mp_prec_t yp, xp;
  1630. yp = y.get_prec();
  1631. xp = x.get_prec();
  1632. a.set_prec(yp>xp?yp:xp);
  1633. mpfr_hypot(a.mp, x.mp, y.mp, rnd_mode);
  1634. return a;
  1635. }
  1636. inline const mpreal remainder (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode)
  1637. {
  1638. mpreal a;
  1639. mp_prec_t yp, xp;
  1640. yp = y.get_prec();
  1641. xp = x.get_prec();
  1642. a.set_prec(yp>xp?yp:xp);
  1643. mpfr_remainder(a.mp, x.mp, y.mp, rnd_mode);
  1644. return a;
  1645. }
  1646. inline const mpreal fac_ui (unsigned long int v, mp_prec_t prec, mp_rnd_t rnd_mode)
  1647. {
  1648. mpreal x(0,prec);
  1649. mpfr_fac_ui(x.mp,v,rnd_mode);
  1650. return x;
  1651. }
  1652. inline const mpreal log1p (const mpreal& v, mp_rnd_t rnd_mode)
  1653. {
  1654. mpreal x(v);
  1655. mpfr_log1p(x.mp,v.mp,rnd_mode);
  1656. return x;
  1657. }
  1658. inline const mpreal expm1 (const mpreal& v, mp_rnd_t rnd_mode)
  1659. {
  1660. mpreal x(v);
  1661. mpfr_expm1(x.mp,v.mp,rnd_mode);
  1662. return x;
  1663. }
  1664. inline const mpreal eint (const mpreal& v, mp_rnd_t rnd_mode)
  1665. {
  1666. mpreal x(v);
  1667. mpfr_eint(x.mp,v.mp,rnd_mode);
  1668. return x;
  1669. }
  1670. inline const mpreal gamma (const mpreal& x, mp_rnd_t rnd_mode)
  1671. {
  1672. mpreal FunctionValue(x);
  1673. // x < 0: gamma(-x) = -pi/(x * gamma(x) * sin(pi*x))
  1674. mpfr_gamma(FunctionValue.mp, x.mp, rnd_mode);
  1675. return FunctionValue;
  1676. }
  1677. inline const mpreal lngamma (const mpreal& v, mp_rnd_t rnd_mode)
  1678. {
  1679. mpreal x(v);
  1680. mpfr_lngamma(x.mp,v.mp,rnd_mode);
  1681. return x;
  1682. }
  1683. inline const mpreal lgamma (const mpreal& v, int *signp, mp_rnd_t rnd_mode)
  1684. {
  1685. mpreal x(v);
  1686. int tsignp;
  1687. if(signp)
  1688. mpfr_lgamma(x.mp,signp,v.mp,rnd_mode);
  1689. else
  1690. mpfr_lgamma(x.mp,&tsignp,v.mp,rnd_mode);
  1691. return x;
  1692. }
  1693. inline const mpreal zeta (const mpreal& v, mp_rnd_t rnd_mode)
  1694. {
  1695. mpreal x(v);
  1696. mpfr_zeta(x.mp,v.mp,rnd_mode);
  1697. return x;
  1698. }
  1699. inline const mpreal erf (const mpreal& v, mp_rnd_t rnd_mode)
  1700. {
  1701. mpreal x(v);
  1702. mpfr_erf(x.mp,v.mp,rnd_mode);
  1703. return x;
  1704. }
  1705. inline const mpreal erfc (const mpreal& v, mp_rnd_t rnd_mode)
  1706. {
  1707. mpreal x(v);
  1708. mpfr_erfc(x.mp,v.mp,rnd_mode);
  1709. return x;
  1710. }
  1711. inline const mpreal besselj0 (const mpreal& v, mp_rnd_t rnd_mode)
  1712. {
  1713. mpreal x(v);
  1714. mpfr_j0(x.mp,v.mp,rnd_mode);
  1715. return x;
  1716. }
  1717. inline const mpreal besselj1 (const mpreal& v, mp_rnd_t rnd_mode)
  1718. {
  1719. mpreal x(v);
  1720. mpfr_j1(x.mp,v.mp,rnd_mode);
  1721. return x;
  1722. }
  1723. inline const mpreal besseljn (long n, const mpreal& v, mp_rnd_t rnd_mode)
  1724. {
  1725. mpreal x(v);
  1726. mpfr_jn(x.mp,n,v.mp,rnd_mode);
  1727. return x;
  1728. }
  1729. inline const mpreal bessely0 (const mpreal& v, mp_rnd_t rnd_mode)
  1730. {
  1731. mpreal x(v);
  1732. mpfr_y0(x.mp,v.mp,rnd_mode);
  1733. return x;
  1734. }
  1735. inline const mpreal bessely1 (const mpreal& v, mp_rnd_t rnd_mode)
  1736. {
  1737. mpreal x(v);
  1738. mpfr_y1(x.mp,v.mp,rnd_mode);
  1739. return x;
  1740. }
  1741. inline const mpreal besselyn (long n, const mpreal& v, mp_rnd_t rnd_mode)
  1742. {
  1743. mpreal x(v);
  1744. mpfr_yn(x.mp,n,v.mp,rnd_mode);
  1745. return x;
  1746. }
  1747. //////////////////////////////////////////////////////////////////////////
  1748. // MPFR 2.4.0 Specifics
  1749. #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
  1750. inline int sinh_cosh(mpreal& s, mpreal& c, const mpreal& v, mp_rnd_t rnd_mode)
  1751. {
  1752. return mpfr_sinh_cosh(s.mp,c.mp,v.mp,rnd_mode);
  1753. }
  1754. inline const mpreal li2(const mpreal& v, mp_rnd_t rnd_mode)
  1755. {
  1756. mpreal x(v);
  1757. mpfr_li2(x.mp,v.mp,rnd_mode);
  1758. return x;
  1759. }
  1760. inline const mpreal fmod (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode)
  1761. {
  1762. mpreal a;
  1763. mp_prec_t yp, xp;
  1764. yp = y.get_prec();
  1765. xp = x.get_prec();
  1766. a.set_prec(yp>xp?yp:xp);
  1767. mpfr_fmod(a.mp, x.mp, y.mp, rnd_mode);
  1768. return a;
  1769. }
  1770. inline const mpreal rec_sqrt(const mpreal& v, mp_rnd_t rnd_mode)
  1771. {
  1772. mpreal x(v);
  1773. mpfr_rec_sqrt(x.mp,v.mp,rnd_mode);
  1774. return x;
  1775. }
  1776. #endif // MPFR 2.4.0 Specifics
  1777. //////////////////////////////////////////////////////////////////////////
  1778. // MPFR 3.0.0 Specifics
  1779. #if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0))
  1780. inline const mpreal digamma(const mpreal& v, mp_rnd_t rnd_mode)
  1781. {
  1782. mpreal x(v);
  1783. mpfr_digamma(x.mp,v.mp,rnd_mode);
  1784. return x;
  1785. }
  1786. inline const mpreal ai(const mpreal& v, mp_rnd_t rnd_mode)
  1787. {
  1788. mpreal x(v);
  1789. mpfr_ai(x.mp,v.mp,rnd_mode);
  1790. return x;
  1791. }
  1792. #endif // MPFR 3.0.0 Specifics
  1793. //////////////////////////////////////////////////////////////////////////
  1794. // Constants
  1795. inline const mpreal const_log2 (mp_prec_t prec, mp_rnd_t rnd_mode)
  1796. {
  1797. mpreal x;
  1798. x.set_prec(prec);
  1799. mpfr_const_log2(x.mp,rnd_mode);
  1800. return x;
  1801. }
  1802. inline const mpreal const_pi (mp_prec_t prec, mp_rnd_t rnd_mode)
  1803. {
  1804. mpreal x;
  1805. x.set_prec(prec);
  1806. mpfr_const_pi(x.mp,rnd_mode);
  1807. return x;
  1808. }
  1809. inline const mpreal const_euler (mp_prec_t prec, mp_rnd_t rnd_mode)
  1810. {
  1811. mpreal x;
  1812. x.set_prec(prec);
  1813. mpfr_const_euler(x.mp,rnd_mode);
  1814. return x;
  1815. }
  1816. inline const mpreal const_catalan (mp_prec_t prec, mp_rnd_t rnd_mode)
  1817. {
  1818. mpreal x;
  1819. x.set_prec(prec);
  1820. mpfr_const_catalan(x.mp,rnd_mode);
  1821. return x;
  1822. }
  1823. inline const mpreal const_infinity (int sign, mp_prec_t prec, mp_rnd_t rnd_mode)
  1824. {
  1825. mpreal x;
  1826. x.set_prec(prec,rnd_mode);
  1827. mpfr_set_inf(x.mp, sign);
  1828. return x;
  1829. }
  1830. //////////////////////////////////////////////////////////////////////////
  1831. // Integer Related Functions
  1832. inline const mpreal rint(const mpreal& v, mp_rnd_t rnd_mode)
  1833. {
  1834. mpreal x(v);
  1835. mpfr_rint(x.mp,v.mp,rnd_mode);
  1836. return x;
  1837. }
  1838. inline const mpreal ceil(const mpreal& v)
  1839. {
  1840. mpreal x(v);
  1841. mpfr_ceil(x.mp,v.mp);
  1842. return x;
  1843. }
  1844. inline const mpreal floor(const mpreal& v)
  1845. {
  1846. mpreal x(v);
  1847. mpfr_floor(x.mp,v.mp);
  1848. return x;
  1849. }
  1850. inline const mpreal round(const mpreal& v)
  1851. {
  1852. mpreal x(v);
  1853. mpfr_round(x.mp,v.mp);
  1854. return x;
  1855. }
  1856. inline const mpreal trunc(const mpreal& v)
  1857. {
  1858. mpreal x(v);
  1859. mpfr_trunc(x.mp,v.mp);
  1860. return x;
  1861. }
  1862. inline const mpreal rint_ceil (const mpreal& v, mp_rnd_t rnd_mode)
  1863. {
  1864. mpreal x(v);
  1865. mpfr_rint_ceil(x.mp,v.mp,rnd_mode);
  1866. return x;
  1867. }
  1868. inline const mpreal rint_floor(const mpreal& v, mp_rnd_t rnd_mode)
  1869. {
  1870. mpreal x(v);
  1871. mpfr_rint_floor(x.mp,v.mp,rnd_mode);
  1872. return x;
  1873. }
  1874. inline const mpreal rint_round(const mpreal& v, mp_rnd_t rnd_mode)
  1875. {
  1876. mpreal x(v);
  1877. mpfr_rint_round(x.mp,v.mp,rnd_mode);
  1878. return x;
  1879. }
  1880. inline const mpreal rint_trunc(const mpreal& v, mp_rnd_t rnd_mode)
  1881. {
  1882. mpreal x(v);
  1883. mpfr_rint_trunc(x.mp,v.mp,rnd_mode);
  1884. return x;
  1885. }
  1886. inline const mpreal frac (const mpreal& v, mp_rnd_t rnd_mode)
  1887. {
  1888. mpreal x(v);
  1889. mpfr_frac(x.mp,v.mp,rnd_mode);
  1890. return x;
  1891. }
  1892. //////////////////////////////////////////////////////////////////////////
  1893. // Miscellaneous Functions
  1894. inline void swap(mpreal& a, mpreal& b)
  1895. {
  1896. mpfr_swap(a.mp,b.mp);
  1897. }
  1898. inline const mpreal (max)(const mpreal& x, const mpreal& y)
  1899. {
  1900. return (x>y?x:y);
  1901. }
  1902. inline const mpreal (min)(const mpreal& x, const mpreal& y)
  1903. {
  1904. return (x<y?x:y);
  1905. }
  1906. inline const mpreal fmax(const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode)
  1907. {
  1908. mpreal a;
  1909. mpfr_max(a.mp,x.mp,y.mp,rnd_mode);
  1910. return a;
  1911. }
  1912. inline const mpreal fmin(const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode)
  1913. {
  1914. mpreal a;
  1915. mpfr_min(a.mp,x.mp,y.mp,rnd_mode);
  1916. return a;
  1917. }
  1918. inline const mpreal nexttoward (const mpreal& x, const mpreal& y)
  1919. {
  1920. mpreal a(x);
  1921. mpfr_nexttoward(a.mp,y.mp);
  1922. return a;
  1923. }
  1924. inline const mpreal nextabove (const mpreal& x)
  1925. {
  1926. mpreal a(x);
  1927. mpfr_nextabove(a.mp);
  1928. return a;
  1929. }
  1930. inline const mpreal nextbelow (const mpreal& x)
  1931. {
  1932. mpreal a(x);
  1933. mpfr_nextbelow(a.mp);
  1934. return a;
  1935. }
  1936. inline const mpreal urandomb (gmp_randstate_t& state)
  1937. {
  1938. mpreal x;
  1939. mpfr_urandomb(x.mp,state);
  1940. return x;
  1941. }
  1942. #if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0))
  1943. // use gmp_randinit_default() to init state, gmp_randclear() to clear
  1944. inline const mpreal urandom (gmp_randstate_t& state, mp_rnd_t rnd_mode)
  1945. {
  1946. mpreal x;
  1947. mpfr_urandom(x.mp,state,rnd_mode);
  1948. return x;
  1949. }
  1950. #endif
  1951. #if (MPFR_VERSION <= MPFR_VERSION_NUM(2,4,2))
  1952. inline const mpreal random2 (mp_size_t size, mp_exp_t exp)
  1953. {
  1954. mpreal x;
  1955. mpfr_random2(x.mp,size,exp);
  1956. return x;
  1957. }
  1958. #endif
  1959. // Uniformly distributed random number generation
  1960. // a = random(seed); <- initialization & first random number generation
  1961. // a = random(); <- next random numbers generation
  1962. // seed != 0
  1963. inline const mpreal random(unsigned int seed)
  1964. {
  1965. #if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0))
  1966. static gmp_randstate_t state;
  1967. static bool isFirstTime = true;
  1968. if(isFirstTime)
  1969. {
  1970. gmp_randinit_default(state);
  1971. gmp_randseed_ui(state,0);
  1972. isFirstTime = false;
  1973. }
  1974. if(seed != 0) gmp_randseed_ui(state,seed);
  1975. return mpfr::urandom(state);
  1976. #else
  1977. if(seed != 0) std::srand(seed);
  1978. return mpfr::mpreal(std::rand()/(double)RAND_MAX);
  1979. #endif
  1980. }
  1981. //////////////////////////////////////////////////////////////////////////
  1982. // Set/Get global properties
  1983. inline void mpreal::set_default_prec(mp_prec_t prec)
  1984. {
  1985. default_prec = prec;
  1986. mpfr_set_default_prec(prec);
  1987. }
  1988. inline mp_prec_t mpreal::get_default_prec()
  1989. {
  1990. return (mpfr_get_default_prec)();
  1991. }
  1992. inline void mpreal::set_default_base(int base)
  1993. {
  1994. default_base = base;
  1995. }
  1996. inline int mpreal::get_default_base()
  1997. {
  1998. return default_base;
  1999. }
  2000. inline void mpreal::set_default_rnd(mp_rnd_t rnd_mode)
  2001. {
  2002. default_rnd = rnd_mode;
  2003. mpfr_set_default_rounding_mode(rnd_mode);
  2004. }
  2005. inline mp_rnd_t mpreal::get_default_rnd()
  2006. {
  2007. return static_cast<mp_rnd_t>((mpfr_get_default_rounding_mode)());
  2008. }
  2009. inline void mpreal::set_double_bits(int dbits)
  2010. {
  2011. double_bits = dbits;
  2012. }
  2013. inline int mpreal::get_double_bits()
  2014. {
  2015. return double_bits;
  2016. }
  2017. inline bool mpreal::fits_in_bits(double x, int n)
  2018. {
  2019. int i;
  2020. double t;
  2021. return IsInf(x) || (std::modf ( std::ldexp ( std::frexp ( x, &i ), n ), &t ) == 0.0);
  2022. }
  2023. inline const mpreal pow(const mpreal& a, const mpreal& b, mp_rnd_t rnd_mode)
  2024. {
  2025. mpreal x(a);
  2026. mpfr_pow(x.mp,x.mp,b.mp,rnd_mode);
  2027. return x;
  2028. }
  2029. inline const mpreal pow(const mpreal& a, const mpz_t b, mp_rnd_t rnd_mode)
  2030. {
  2031. mpreal x(a);
  2032. mpfr_pow_z(x.mp,x.mp,b,rnd_mode);
  2033. return x;
  2034. }
  2035. inline const mpreal pow(const mpreal& a, const unsigned long int b, mp_rnd_t rnd_mode)
  2036. {
  2037. mpreal x(a);
  2038. mpfr_pow_ui(x.mp,x.mp,b,rnd_mode);
  2039. return x;
  2040. }
  2041. inline const mpreal pow(const mpreal& a, const unsigned int b, mp_rnd_t rnd_mode)
  2042. {
  2043. return pow(a,static_cast<unsigned long int>(b),rnd_mode);
  2044. }
  2045. inline const mpreal pow(const mpreal& a, const long int b, mp_rnd_t rnd_mode)
  2046. {
  2047. mpreal x(a);
  2048. mpfr_pow_si(x.mp,x.mp,b,rnd_mode);
  2049. return x;
  2050. }
  2051. inline const mpreal pow(const mpreal& a, const int b, mp_rnd_t rnd_mode)
  2052. {
  2053. return pow(a,static_cast<long int>(b),rnd_mode);
  2054. }
  2055. inline const mpreal pow(const mpreal& a, const long double b, mp_rnd_t rnd_mode)
  2056. {
  2057. return pow(a,mpreal(b),rnd_mode);
  2058. }
  2059. inline const mpreal pow(const mpreal& a, const double b, mp_rnd_t rnd_mode)
  2060. {
  2061. return pow(a,mpreal(b),rnd_mode);
  2062. }
  2063. inline const mpreal pow(const unsigned long int a, const mpreal& b, mp_rnd_t rnd_mode)
  2064. {
  2065. mpreal x(a);
  2066. mpfr_ui_pow(x.mp,a,b.mp,rnd_mode);
  2067. return x;
  2068. }
  2069. inline const mpreal pow(const unsigned int a, const mpreal& b, mp_rnd_t rnd_mode)
  2070. {
  2071. return pow(static_cast<unsigned long int>(a),b,rnd_mode);
  2072. }
  2073. inline const mpreal pow(const long int a, const mpreal& b, mp_rnd_t rnd_mode)
  2074. {
  2075. if (a>=0) return pow(static_cast<unsigned long int>(a),b,rnd_mode);
  2076. else return pow(mpreal(a),b,rnd_mode);
  2077. }
  2078. inline const mpreal pow(const int a, const mpreal& b, mp_rnd_t rnd_mode)
  2079. {
  2080. if (a>=0) return pow(static_cast<unsigned long int>(a),b,rnd_mode);
  2081. else return pow(mpreal(a),b,rnd_mode);
  2082. }
  2083. inline const mpreal pow(const long double a, const mpreal& b, mp_rnd_t rnd_mode)
  2084. {
  2085. return pow(mpreal(a),b,rnd_mode);
  2086. }
  2087. inline const mpreal pow(const double a, const mpreal& b, mp_rnd_t rnd_mode)
  2088. {
  2089. return pow(mpreal(a),b,rnd_mode);
  2090. }
  2091. // pow unsigned long int
  2092. inline const mpreal pow(const unsigned long int a, const unsigned long int b, mp_rnd_t rnd_mode)
  2093. {
  2094. mpreal x(a);
  2095. mpfr_ui_pow_ui(x.mp,a,b,rnd_mode);
  2096. return x;
  2097. }
  2098. inline const mpreal pow(const unsigned long int a, const unsigned int b, mp_rnd_t rnd_mode)
  2099. {
  2100. return pow(a,static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
  2101. }
  2102. inline const mpreal pow(const unsigned long int a, const long int b, mp_rnd_t rnd_mode)
  2103. {
  2104. if(b>0) return pow(a,static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
  2105. else return pow(a,mpreal(b),rnd_mode); //mpfr_ui_pow
  2106. }
  2107. inline const mpreal pow(const unsigned long int a, const int b, mp_rnd_t rnd_mode)
  2108. {
  2109. if(b>0) return pow(a,static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
  2110. else return pow(a,mpreal(b),rnd_mode); //mpfr_ui_pow
  2111. }
  2112. inline const mpreal pow(const unsigned long int a, const long double b, mp_rnd_t rnd_mode)
  2113. {
  2114. return pow(a,mpreal(b),rnd_mode); //mpfr_ui_pow
  2115. }
  2116. inline const mpreal pow(const unsigned long int a, const double b, mp_rnd_t rnd_mode)
  2117. {
  2118. return pow(a,mpreal(b),rnd_mode); //mpfr_ui_pow
  2119. }
  2120. // pow unsigned int
  2121. inline const mpreal pow(const unsigned int a, const unsigned long int b, mp_rnd_t rnd_mode)
  2122. {
  2123. return pow(static_cast<unsigned long int>(a),b,rnd_mode); //mpfr_ui_pow_ui
  2124. }
  2125. inline const mpreal pow(const unsigned int a, const unsigned int b, mp_rnd_t rnd_mode)
  2126. {
  2127. return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
  2128. }
  2129. inline const mpreal pow(const unsigned int a, const long int b, mp_rnd_t rnd_mode)
  2130. {
  2131. if(b>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
  2132. else return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
  2133. }
  2134. inline const mpreal pow(const unsigned int a, const int b, mp_rnd_t rnd_mode)
  2135. {
  2136. if(b>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
  2137. else return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
  2138. }
  2139. inline const mpreal pow(const unsigned int a, const long double b, mp_rnd_t rnd_mode)
  2140. {
  2141. return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
  2142. }
  2143. inline const mpreal pow(const unsigned int a, const double b, mp_rnd_t rnd_mode)
  2144. {
  2145. return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
  2146. }
  2147. // pow long int
  2148. inline const mpreal pow(const long int a, const unsigned long int b, mp_rnd_t rnd_mode)
  2149. {
  2150. if (a>0) return pow(static_cast<unsigned long int>(a),b,rnd_mode); //mpfr_ui_pow_ui
  2151. else return pow(mpreal(a),b,rnd_mode); //mpfr_pow_ui
  2152. }
  2153. inline const mpreal pow(const long int a, const unsigned int b, mp_rnd_t rnd_mode)
  2154. {
  2155. if (a>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
  2156. else return pow(mpreal(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_pow_ui
  2157. }
  2158. inline const mpreal pow(const long int a, const long int b, mp_rnd_t rnd_mode)
  2159. {
  2160. if (a>0)
  2161. {
  2162. if(b>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
  2163. else return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
  2164. }else{
  2165. return pow(mpreal(a),b,rnd_mode); // mpfr_pow_si
  2166. }
  2167. }
  2168. inline const mpreal pow(const long int a, const int b, mp_rnd_t rnd_mode)
  2169. {
  2170. if (a>0)
  2171. {
  2172. if(b>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
  2173. else return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
  2174. }else{
  2175. return pow(mpreal(a),static_cast<long int>(b),rnd_mode); // mpfr_pow_si
  2176. }
  2177. }
  2178. inline const mpreal pow(const long int a, const long double b, mp_rnd_t rnd_mode)
  2179. {
  2180. if (a>=0) return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
  2181. else return pow(mpreal(a),mpreal(b),rnd_mode); //mpfr_pow
  2182. }
  2183. inline const mpreal pow(const long int a, const double b, mp_rnd_t rnd_mode)
  2184. {
  2185. if (a>=0) return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
  2186. else return pow(mpreal(a),mpreal(b),rnd_mode); //mpfr_pow
  2187. }
  2188. // pow int
  2189. inline const mpreal pow(const int a, const unsigned long int b, mp_rnd_t rnd_mode)
  2190. {
  2191. if (a>0) return pow(static_cast<unsigned long int>(a),b,rnd_mode); //mpfr_ui_pow_ui
  2192. else return pow(mpreal(a),b,rnd_mode); //mpfr_pow_ui
  2193. }
  2194. inline const mpreal pow(const int a, const unsigned int b, mp_rnd_t rnd_mode)
  2195. {
  2196. if (a>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
  2197. else return pow(mpreal(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_pow_ui
  2198. }
  2199. inline const mpreal pow(const int a, const long int b, mp_rnd_t rnd_mode)
  2200. {
  2201. if (a>0)
  2202. {
  2203. if(b>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
  2204. else return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
  2205. }else{
  2206. return pow(mpreal(a),b,rnd_mode); // mpfr_pow_si
  2207. }
  2208. }
  2209. inline const mpreal pow(const int a, const int b, mp_rnd_t rnd_mode)
  2210. {
  2211. if (a>0)
  2212. {
  2213. if(b>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
  2214. else return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
  2215. }else{
  2216. return pow(mpreal(a),static_cast<long int>(b),rnd_mode); // mpfr_pow_si
  2217. }
  2218. }
  2219. inline const mpreal pow(const int a, const long double b, mp_rnd_t rnd_mode)
  2220. {
  2221. if (a>=0) return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
  2222. else return pow(mpreal(a),mpreal(b),rnd_mode); //mpfr_pow
  2223. }
  2224. inline const mpreal pow(const int a, const double b, mp_rnd_t rnd_mode)
  2225. {
  2226. if (a>=0) return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
  2227. else return pow(mpreal(a),mpreal(b),rnd_mode); //mpfr_pow
  2228. }
  2229. // pow long double
  2230. inline const mpreal pow(const long double a, const long double b, mp_rnd_t rnd_mode)
  2231. {
  2232. return pow(mpreal(a),mpreal(b),rnd_mode);
  2233. }
  2234. inline const mpreal pow(const long double a, const unsigned long int b, mp_rnd_t rnd_mode)
  2235. {
  2236. return pow(mpreal(a),b,rnd_mode); //mpfr_pow_ui
  2237. }
  2238. inline const mpreal pow(const long double a, const unsigned int b, mp_rnd_t rnd_mode)
  2239. {
  2240. return pow(mpreal(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_pow_ui
  2241. }
  2242. inline const mpreal pow(const long double a, const long int b, mp_rnd_t rnd_mode)
  2243. {
  2244. return pow(mpreal(a),b,rnd_mode); // mpfr_pow_si
  2245. }
  2246. inline const mpreal pow(const long double a, const int b, mp_rnd_t rnd_mode)
  2247. {
  2248. return pow(mpreal(a),static_cast<long int>(b),rnd_mode); // mpfr_pow_si
  2249. }
  2250. inline const mpreal pow(const double a, const double b, mp_rnd_t rnd_mode)
  2251. {
  2252. return pow(mpreal(a),mpreal(b),rnd_mode);
  2253. }
  2254. inline const mpreal pow(const double a, const unsigned long int b, mp_rnd_t rnd_mode)
  2255. {
  2256. return pow(mpreal(a),b,rnd_mode); // mpfr_pow_ui
  2257. }
  2258. inline const mpreal pow(const double a, const unsigned int b, mp_rnd_t rnd_mode)
  2259. {
  2260. return pow(mpreal(a),static_cast<unsigned long int>(b),rnd_mode); // mpfr_pow_ui
  2261. }
  2262. inline const mpreal pow(const double a, const long int b, mp_rnd_t rnd_mode)
  2263. {
  2264. return pow(mpreal(a),b,rnd_mode); // mpfr_pow_si
  2265. }
  2266. inline const mpreal pow(const double a, const int b, mp_rnd_t rnd_mode)
  2267. {
  2268. return pow(mpreal(a),static_cast<long int>(b),rnd_mode); // mpfr_pow_si
  2269. }
  2270. } // End of mpfr namespace
  2271. // Explicit specialization of std::swap for mpreal numbers
  2272. // Thus standard algorithms will use efficient version of swap (due to Koenig lookup)
  2273. // Non-throwing swap C++ idiom: http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-throwing_swap
  2274. namespace std
  2275. {
  2276. template <>
  2277. inline void swap(mpfr::mpreal& x, mpfr::mpreal& y)
  2278. {
  2279. return mpfr::swap(x, y);
  2280. }
  2281. }
  2282. #endif /* __MPREAL_H__ */