qd_real.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. /*
  2. * include/qd_real.h
  3. *
  4. * This work was supported by the Director, Office of Science, Division
  5. * of Mathematical, Information, and Computational Sciences of the
  6. * U.S. Department of Energy under contract number DE-AC03-76SF00098.
  7. *
  8. * Copyright (c) 2000-2007
  9. *
  10. * Quad-double precision (>= 212-bit significand) floating point arithmetic
  11. * package, written in ANSI C++, taking full advantage of operator overloading.
  12. * Uses similar techniques as that of David Bailey's double-double package
  13. * and that of Jonathan Shewchuk's adaptive precision floating point
  14. * arithmetic package. See
  15. *
  16. * http://www.nersc.gov/~dhbailey/mpdist/mpdist.html
  17. * http://www.cs.cmu.edu/~quake/robust.html
  18. *
  19. * for more details.
  20. *
  21. * Yozo Hida
  22. */
  23. #ifndef _QD_QD_REAL_H
  24. #define _QD_QD_REAL_H
  25. #include <iostream>
  26. #include <string>
  27. #include <limits>
  28. #include <qd/qd_config.h>
  29. #include <qd/dd_real.h>
  30. struct QD_API qd_real {
  31. double x[4]; /* The Components. */
  32. /* Eliminates any zeros in the middle component(s). */
  33. void zero_elim();
  34. void zero_elim(double &e);
  35. void renorm();
  36. void renorm(double &e);
  37. void quick_accum(double d, double &e);
  38. void quick_prod_accum(double a, double b, double &e);
  39. qd_real(double x0, double x1, double x2, double x3);
  40. explicit qd_real(const double *xx);
  41. static const qd_real _2pi;
  42. static const qd_real _pi;
  43. static const qd_real _3pi4;
  44. static const qd_real _pi2;
  45. static const qd_real _pi4;
  46. static const qd_real _e;
  47. static const qd_real _log2;
  48. static const qd_real _log10;
  49. static const qd_real _nan;
  50. static const qd_real _inf;
  51. static const double _eps;
  52. static const double _min_normalized;
  53. static const qd_real _max;
  54. static const qd_real _safe_max;
  55. static const int _ndigits;
  56. qd_real();
  57. qd_real(const char *s);
  58. qd_real(const dd_real &dd);
  59. qd_real(double d);
  60. qd_real(int i);
  61. double operator[](int i) const;
  62. double &operator[](int i);
  63. static void error(const char *msg);
  64. bool isnan() const;
  65. bool isfinite() const { return QD_ISFINITE(x[0]); }
  66. bool isinf() const { return QD_ISINF(x[0]); }
  67. static qd_real ieee_add(const qd_real &a, const qd_real &b);
  68. static qd_real sloppy_add(const qd_real &a, const qd_real &b);
  69. qd_real &operator+=(double a);
  70. qd_real &operator+=(const dd_real &a);
  71. qd_real &operator+=(const qd_real &a);
  72. qd_real &operator-=(double a);
  73. qd_real &operator-=(const dd_real &a);
  74. qd_real &operator-=(const qd_real &a);
  75. static qd_real sloppy_mul(const qd_real &a, const qd_real &b);
  76. static qd_real accurate_mul(const qd_real &a, const qd_real &b);
  77. qd_real &operator*=(double a);
  78. qd_real &operator*=(const dd_real &a);
  79. qd_real &operator*=(const qd_real &a);
  80. static qd_real sloppy_div(const qd_real &a, const dd_real &b);
  81. static qd_real accurate_div(const qd_real &a, const dd_real &b);
  82. static qd_real sloppy_div(const qd_real &a, const qd_real &b);
  83. static qd_real accurate_div(const qd_real &a, const qd_real &b);
  84. qd_real &operator/=(double a);
  85. qd_real &operator/=(const dd_real &a);
  86. qd_real &operator/=(const qd_real &a);
  87. qd_real operator^(int n) const;
  88. qd_real operator-() const;
  89. qd_real &operator=(double a);
  90. qd_real &operator=(const dd_real &a);
  91. qd_real &operator=(const char *s);
  92. bool is_zero() const;
  93. bool is_one() const;
  94. bool is_positive() const;
  95. bool is_negative() const;
  96. static qd_real rand(void);
  97. void to_digits(char *s, int &expn, int precision = _ndigits) const;
  98. void write(char *s, int len, int precision = _ndigits,
  99. bool showpos = false, bool uppercase = false) const;
  100. std::string to_string(int precision = _ndigits, int width = 0,
  101. std::ios_base::fmtflags fmt = static_cast<std::ios_base::fmtflags>(0),
  102. bool showpos = false, bool uppercase = false, char fill = ' ') const;
  103. static int read(const char *s, qd_real &a);
  104. /* Debugging methods */
  105. void dump(const std::string &name = "", std::ostream &os = std::cerr) const;
  106. void dump_bits(const std::string &name = "",
  107. std::ostream &os = std::cerr) const;
  108. static qd_real debug_rand();
  109. };
  110. namespace std {
  111. template <>
  112. class numeric_limits<qd_real> : public numeric_limits<double> {
  113. public:
  114. inline static double epsilon() { return qd_real::_eps; }
  115. inline static double min() { return qd_real::_min_normalized; }
  116. inline static qd_real max() { return qd_real::_max; }
  117. inline static qd_real safe_max() { return qd_real::_safe_max; }
  118. static const int digits = 209;
  119. static const int digits10 = 62;
  120. };
  121. }
  122. QD_API qd_real polyeval(const qd_real *c, int n, const qd_real &x);
  123. QD_API qd_real polyroot(const qd_real *c, int n,
  124. const qd_real &x0, int max_iter = 64, double thresh = 0.0);
  125. QD_API qd_real qdrand(void);
  126. QD_API qd_real sqrt(const qd_real &a);
  127. QD_API inline bool isnan(const qd_real &a) { return a.isnan(); }
  128. QD_API inline bool isfinite(const qd_real &a) { return a.isfinite(); }
  129. QD_API inline bool isinf(const qd_real &a) { return a.isinf(); }
  130. /* Computes qd * d where d is known to be a power of 2.
  131. This can be done component wise. */
  132. QD_API qd_real mul_pwr2(const qd_real &qd, double d);
  133. QD_API qd_real operator+(const qd_real &a, const qd_real &b);
  134. QD_API qd_real operator+(const dd_real &a, const qd_real &b);
  135. QD_API qd_real operator+(const qd_real &a, const dd_real &b);
  136. QD_API qd_real operator+(const qd_real &a, double b);
  137. QD_API qd_real operator+(double a, const qd_real &b);
  138. QD_API qd_real operator-(const qd_real &a, const qd_real &b);
  139. QD_API qd_real operator-(const dd_real &a, const qd_real &b);
  140. QD_API qd_real operator-(const qd_real &a, const dd_real &b);
  141. QD_API qd_real operator-(const qd_real &a, double b);
  142. QD_API qd_real operator-(double a, const qd_real &b);
  143. QD_API qd_real operator*(const qd_real &a, const qd_real &b);
  144. QD_API qd_real operator*(const dd_real &a, const qd_real &b);
  145. QD_API qd_real operator*(const qd_real &a, const dd_real &b);
  146. QD_API qd_real operator*(const qd_real &a, double b);
  147. QD_API qd_real operator*(double a, const qd_real &b);
  148. QD_API qd_real operator/(const qd_real &a, const qd_real &b);
  149. QD_API qd_real operator/(const dd_real &a, const qd_real &b);
  150. QD_API qd_real operator/(const qd_real &a, const dd_real &b);
  151. QD_API qd_real operator/(const qd_real &a, double b);
  152. QD_API qd_real operator/(double a, const qd_real &b);
  153. QD_API qd_real sqr(const qd_real &a);
  154. QD_API qd_real sqrt(const qd_real &a);
  155. QD_API qd_real pow(const qd_real &a, int n);
  156. QD_API qd_real pow(const qd_real &a, const qd_real &b);
  157. QD_API qd_real npwr(const qd_real &a, int n);
  158. QD_API qd_real nroot(const qd_real &a, int n);
  159. QD_API qd_real rem(const qd_real &a, const qd_real &b);
  160. QD_API qd_real drem(const qd_real &a, const qd_real &b);
  161. QD_API qd_real divrem(const qd_real &a, const qd_real &b, qd_real &r);
  162. dd_real to_dd_real(const qd_real &a);
  163. double to_double(const qd_real &a);
  164. int to_int(const qd_real &a);
  165. QD_API bool operator==(const qd_real &a, const qd_real &b);
  166. QD_API bool operator==(const qd_real &a, const dd_real &b);
  167. QD_API bool operator==(const dd_real &a, const qd_real &b);
  168. QD_API bool operator==(double a, const qd_real &b);
  169. QD_API bool operator==(const qd_real &a, double b);
  170. QD_API bool operator<(const qd_real &a, const qd_real &b);
  171. QD_API bool operator<(const qd_real &a, const dd_real &b);
  172. QD_API bool operator<(const dd_real &a, const qd_real &b);
  173. QD_API bool operator<(double a, const qd_real &b);
  174. QD_API bool operator<(const qd_real &a, double b);
  175. QD_API bool operator>(const qd_real &a, const qd_real &b);
  176. QD_API bool operator>(const qd_real &a, const dd_real &b);
  177. QD_API bool operator>(const dd_real &a, const qd_real &b);
  178. QD_API bool operator>(double a, const qd_real &b);
  179. QD_API bool operator>(const qd_real &a, double b);
  180. QD_API bool operator<=(const qd_real &a, const qd_real &b);
  181. QD_API bool operator<=(const qd_real &a, const dd_real &b);
  182. QD_API bool operator<=(const dd_real &a, const qd_real &b);
  183. QD_API bool operator<=(double a, const qd_real &b);
  184. QD_API bool operator<=(const qd_real &a, double b);
  185. QD_API bool operator>=(const qd_real &a, const qd_real &b);
  186. QD_API bool operator>=(const qd_real &a, const dd_real &b);
  187. QD_API bool operator>=(const dd_real &a, const qd_real &b);
  188. QD_API bool operator>=(double a, const qd_real &b);
  189. QD_API bool operator>=(const qd_real &a, double b);
  190. QD_API bool operator!=(const qd_real &a, const qd_real &b);
  191. QD_API bool operator!=(const qd_real &a, const dd_real &b);
  192. QD_API bool operator!=(const dd_real &a, const qd_real &b);
  193. QD_API bool operator!=(double a, const qd_real &b);
  194. QD_API bool operator!=(const qd_real &a, double b);
  195. QD_API qd_real fabs(const qd_real &a);
  196. QD_API qd_real abs(const qd_real &a); /* same as fabs */
  197. QD_API qd_real ldexp(const qd_real &a, int n);
  198. QD_API qd_real nint(const qd_real &a);
  199. QD_API qd_real quick_nint(const qd_real &a);
  200. QD_API qd_real floor(const qd_real &a);
  201. QD_API qd_real ceil(const qd_real &a);
  202. QD_API qd_real aint(const qd_real &a);
  203. QD_API qd_real sin(const qd_real &a);
  204. QD_API qd_real cos(const qd_real &a);
  205. QD_API qd_real tan(const qd_real &a);
  206. QD_API void sincos(const qd_real &a, qd_real &s, qd_real &c);
  207. QD_API qd_real asin(const qd_real &a);
  208. QD_API qd_real acos(const qd_real &a);
  209. QD_API qd_real atan(const qd_real &a);
  210. QD_API qd_real atan2(const qd_real &y, const qd_real &x);
  211. QD_API qd_real exp(const qd_real &a);
  212. QD_API qd_real log(const qd_real &a);
  213. QD_API qd_real log10(const qd_real &a);
  214. QD_API qd_real sinh(const qd_real &a);
  215. QD_API qd_real cosh(const qd_real &a);
  216. QD_API qd_real tanh(const qd_real &a);
  217. QD_API void sincosh(const qd_real &a, qd_real &sin_qd, qd_real &cos_qd);
  218. QD_API qd_real asinh(const qd_real &a);
  219. QD_API qd_real acosh(const qd_real &a);
  220. QD_API qd_real atanh(const qd_real &a);
  221. QD_API qd_real qdrand(void);
  222. QD_API qd_real max(const qd_real &a, const qd_real &b);
  223. QD_API qd_real max(const qd_real &a, const qd_real &b, const qd_real &c);
  224. QD_API qd_real min(const qd_real &a, const qd_real &b);
  225. QD_API qd_real min(const qd_real &a, const qd_real &b, const qd_real &c);
  226. QD_API qd_real fmod(const qd_real &a, const qd_real &b);
  227. QD_API std::ostream &operator<<(std::ostream &s, const qd_real &a);
  228. QD_API std::istream &operator>>(std::istream &s, qd_real &a);
  229. #ifdef QD_INLINE
  230. #include <qd/qd_inline.h>
  231. #endif
  232. #endif /* _QD_QD_REAL_H */