dd_real.h 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. /*
  2. * include/dd_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. * Double-double precision (>= 106-bit significand) floating point
  11. * arithmetic package based on David Bailey's Fortran-90 double-double
  12. * package, with some changes. See
  13. *
  14. * http://www.nersc.gov/~dhbailey/mpdist/mpdist.html
  15. *
  16. * for the original Fortran-90 version.
  17. *
  18. * Overall structure is similar to that of Keith Brigg's C++ double-double
  19. * package. See
  20. *
  21. * http://www-epidem.plansci.cam.ac.uk/~kbriggs/doubledouble.html
  22. *
  23. * for more details. In particular, the fix for x86 computers is borrowed
  24. * from his code.
  25. *
  26. * Yozo Hida
  27. */
  28. #ifndef _QD_DD_REAL_H
  29. #define _QD_DD_REAL_H
  30. #include <cmath>
  31. #include <iostream>
  32. #include <string>
  33. #include <limits>
  34. #include <qd/qd_config.h>
  35. #include <qd/fpu.h>
  36. // Some compilers define isnan, isfinite, and isinf as macros, even for
  37. // C++ codes, which cause havoc when overloading these functions. We undef
  38. // them here.
  39. #ifdef isnan
  40. #undef isnan
  41. #endif
  42. #ifdef isfinite
  43. #undef isfinite
  44. #endif
  45. #ifdef isinf
  46. #undef isinf
  47. #endif
  48. #ifdef max
  49. #undef max
  50. #endif
  51. #ifdef min
  52. #undef min
  53. #endif
  54. struct QD_API dd_real {
  55. double x[2];
  56. dd_real(double hi, double lo) { x[0] = hi; x[1] = lo; }
  57. dd_real() {x[0] = 0.0; x[1] = 0.0; }
  58. dd_real(double h) { x[0] = h; x[1] = 0.0; }
  59. dd_real(int h) {
  60. x[0] = (static_cast<double>(h));
  61. x[1] = 0.0;
  62. }
  63. dd_real (const char *s);
  64. explicit dd_real (const double *d) {
  65. x[0] = d[0]; x[1] = d[1];
  66. }
  67. static void error(const char *msg);
  68. double _hi() const { return x[0]; }
  69. double _lo() const { return x[1]; }
  70. static const dd_real _2pi;
  71. static const dd_real _pi;
  72. static const dd_real _3pi4;
  73. static const dd_real _pi2;
  74. static const dd_real _pi4;
  75. static const dd_real _e;
  76. static const dd_real _log2;
  77. static const dd_real _log10;
  78. static const dd_real _nan;
  79. static const dd_real _inf;
  80. static const double _eps;
  81. static const double _min_normalized;
  82. static const dd_real _max;
  83. static const dd_real _safe_max;
  84. static const int _ndigits;
  85. bool isnan() const { return QD_ISNAN(x[0]) || QD_ISNAN(x[1]); }
  86. bool isfinite() const { return QD_ISFINITE(x[0]); }
  87. bool isinf() const { return QD_ISINF(x[0]); }
  88. static dd_real add(double a, double b);
  89. static dd_real ieee_add(const dd_real &a, const dd_real &b);
  90. static dd_real sloppy_add(const dd_real &a, const dd_real &b);
  91. dd_real &operator+=(double a);
  92. dd_real &operator+=(const dd_real &a);
  93. static dd_real sub(double a, double b);
  94. dd_real &operator-=(double a);
  95. dd_real &operator-=(const dd_real &a);
  96. dd_real operator-() const;
  97. static dd_real mul(double a, double b);
  98. dd_real &operator*=(double a);
  99. dd_real &operator*=(const dd_real &a);
  100. static dd_real div(double a, double b);
  101. static dd_real sloppy_div(const dd_real &a, const dd_real &b);
  102. static dd_real accurate_div(const dd_real &a, const dd_real &b);
  103. dd_real &operator/=(double a);
  104. dd_real &operator/=(const dd_real &a);
  105. dd_real &operator=(double a);
  106. dd_real &operator=(const char *s);
  107. dd_real operator^(int n);
  108. static dd_real sqr(double d);
  109. static dd_real sqrt(double a);
  110. bool is_zero() const;
  111. bool is_one() const;
  112. bool is_positive() const;
  113. bool is_negative() const;
  114. static dd_real rand(void);
  115. void to_digits(char *s, int &expn, int precision = _ndigits) const;
  116. void write(char *s, int len, int precision = _ndigits,
  117. bool showpos = false, bool uppercase = false) const;
  118. std::string to_string(int precision = _ndigits, int width = 0,
  119. std::ios_base::fmtflags fmt = static_cast<std::ios_base::fmtflags>(0),
  120. bool showpos = false, bool uppercase = false, char fill = ' ') const;
  121. int read(const char *s, dd_real &a);
  122. /* Debugging Methods */
  123. void dump(const std::string &name = "", std::ostream &os = std::cerr) const;
  124. void dump_bits(const std::string &name = "",
  125. std::ostream &os = std::cerr) const;
  126. static dd_real debug_rand();
  127. };
  128. namespace std {
  129. template <>
  130. class numeric_limits<dd_real> : public numeric_limits<double> {
  131. public:
  132. inline static double epsilon() { return dd_real::_eps; }
  133. inline static dd_real max() { return dd_real::_max; }
  134. inline static dd_real safe_max() { return dd_real::_safe_max; }
  135. inline static double min() { return dd_real::_min_normalized; }
  136. static const int digits = 104;
  137. static const int digits10 = 31;
  138. };
  139. }
  140. QD_API dd_real ddrand(void);
  141. QD_API dd_real sqrt(const dd_real &a);
  142. QD_API dd_real polyeval(const dd_real *c, int n, const dd_real &x);
  143. QD_API dd_real polyroot(const dd_real *c, int n,
  144. const dd_real &x0, int max_iter = 32, double thresh = 0.0);
  145. QD_API inline bool isnan(const dd_real &a) { return a.isnan(); }
  146. QD_API inline bool isfinite(const dd_real &a) { return a.isfinite(); }
  147. QD_API inline bool isinf(const dd_real &a) { return a.isinf(); }
  148. /* Computes dd * d where d is known to be a power of 2. */
  149. QD_API dd_real mul_pwr2(const dd_real &dd, double d);
  150. QD_API dd_real operator+(const dd_real &a, double b);
  151. QD_API dd_real operator+(double a, const dd_real &b);
  152. QD_API dd_real operator+(const dd_real &a, const dd_real &b);
  153. QD_API dd_real operator-(const dd_real &a, double b);
  154. QD_API dd_real operator-(double a, const dd_real &b);
  155. QD_API dd_real operator-(const dd_real &a, const dd_real &b);
  156. QD_API dd_real operator*(const dd_real &a, double b);
  157. QD_API dd_real operator*(double a, const dd_real &b);
  158. QD_API dd_real operator*(const dd_real &a, const dd_real &b);
  159. QD_API dd_real operator/(const dd_real &a, double b);
  160. QD_API dd_real operator/(double a, const dd_real &b);
  161. QD_API dd_real operator/(const dd_real &a, const dd_real &b);
  162. QD_API dd_real inv(const dd_real &a);
  163. QD_API dd_real rem(const dd_real &a, const dd_real &b);
  164. QD_API dd_real drem(const dd_real &a, const dd_real &b);
  165. QD_API dd_real divrem(const dd_real &a, const dd_real &b, dd_real &r);
  166. QD_API dd_real pow(const dd_real &a, int n);
  167. QD_API dd_real pow(const dd_real &a, const dd_real &b);
  168. QD_API dd_real npwr(const dd_real &a, int n);
  169. QD_API dd_real sqr(const dd_real &a);
  170. QD_API dd_real sqrt(const dd_real &a);
  171. QD_API dd_real nroot(const dd_real &a, int n);
  172. QD_API bool operator==(const dd_real &a, double b);
  173. QD_API bool operator==(double a, const dd_real &b);
  174. QD_API bool operator==(const dd_real &a, const dd_real &b);
  175. QD_API bool operator<=(const dd_real &a, double b);
  176. QD_API bool operator<=(double a, const dd_real &b);
  177. QD_API bool operator<=(const dd_real &a, const dd_real &b);
  178. QD_API bool operator>=(const dd_real &a, double b);
  179. QD_API bool operator>=(double a, const dd_real &b);
  180. QD_API bool operator>=(const dd_real &a, const dd_real &b);
  181. QD_API bool operator<(const dd_real &a, double b);
  182. QD_API bool operator<(double a, const dd_real &b);
  183. QD_API bool operator<(const dd_real &a, const dd_real &b);
  184. QD_API bool operator>(const dd_real &a, double b);
  185. QD_API bool operator>(double a, const dd_real &b);
  186. QD_API bool operator>(const dd_real &a, const dd_real &b);
  187. QD_API bool operator!=(const dd_real &a, double b);
  188. QD_API bool operator!=(double a, const dd_real &b);
  189. QD_API bool operator!=(const dd_real &a, const dd_real &b);
  190. QD_API dd_real nint(const dd_real &a);
  191. QD_API dd_real floor(const dd_real &a);
  192. QD_API dd_real ceil(const dd_real &a);
  193. QD_API dd_real aint(const dd_real &a);
  194. QD_API dd_real ddrand(void);
  195. double to_double(const dd_real &a);
  196. int to_int(const dd_real &a);
  197. QD_API dd_real exp(const dd_real &a);
  198. QD_API dd_real ldexp(const dd_real &a, int exp);
  199. QD_API dd_real log(const dd_real &a);
  200. QD_API dd_real log10(const dd_real &a);
  201. QD_API dd_real sin(const dd_real &a);
  202. QD_API dd_real cos(const dd_real &a);
  203. QD_API dd_real tan(const dd_real &a);
  204. QD_API void sincos(const dd_real &a, dd_real &sin_a, dd_real &cos_a);
  205. QD_API dd_real asin(const dd_real &a);
  206. QD_API dd_real acos(const dd_real &a);
  207. QD_API dd_real atan(const dd_real &a);
  208. QD_API dd_real atan2(const dd_real &y, const dd_real &x);
  209. QD_API dd_real sinh(const dd_real &a);
  210. QD_API dd_real cosh(const dd_real &a);
  211. QD_API dd_real tanh(const dd_real &a);
  212. QD_API void sincosh(const dd_real &a,
  213. dd_real &sinh_a, dd_real &cosh_a);
  214. QD_API dd_real asinh(const dd_real &a);
  215. QD_API dd_real acosh(const dd_real &a);
  216. QD_API dd_real atanh(const dd_real &a);
  217. QD_API dd_real fabs(const dd_real &a);
  218. QD_API dd_real abs(const dd_real &a); /* same as fabs */
  219. QD_API dd_real fmod(const dd_real &a, const dd_real &b);
  220. QD_API std::ostream& operator<<(std::ostream &s, const dd_real &a);
  221. QD_API std::istream& operator>>(std::istream &s, dd_real &a);
  222. #ifdef QD_INLINE
  223. #include <qd/dd_inline.h>
  224. #endif
  225. #endif /* _QD_DD_REAL_H */