inline.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /*
  2. * include/inline.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-2001
  9. *
  10. * This file contains the basic functions used both by double-double
  11. * and quad-double package. These are declared as inline functions as
  12. * they are the smallest building blocks of the double-double and
  13. * quad-double arithmetic.
  14. */
  15. #ifndef _QD_INLINE_H
  16. #define _QD_INLINE_H
  17. #define _QD_SPLITTER 134217729.0 // = 2^27 + 1
  18. #define _QD_SPLIT_THRESH 6.69692879491417e+299 // = 2^996
  19. #ifdef QD_VACPP_BUILTINS_H
  20. /* For VisualAge C++ __fmadd */
  21. #include <builtins.h>
  22. #endif
  23. #include <cmath>
  24. #include <limits>
  25. namespace qd {
  26. static const double _d_nan = std::numeric_limits<double>::quiet_NaN();
  27. static const double _d_inf = std::numeric_limits<double>::infinity();
  28. /*********** Basic Functions ************/
  29. /* Computes fl(a+b) and err(a+b). Assumes |a| >= |b|. */
  30. inline double quick_two_sum(double a, double b, double &err) {
  31. double s = a + b;
  32. err = b - (s - a);
  33. return s;
  34. }
  35. /* Computes fl(a-b) and err(a-b). Assumes |a| >= |b| */
  36. inline double quick_two_diff(double a, double b, double &err) {
  37. double s = a - b;
  38. err = (a - s) - b;
  39. return s;
  40. }
  41. /* Computes fl(a+b) and err(a+b). */
  42. inline double two_sum(double a, double b, double &err) {
  43. double s = a + b;
  44. double bb = s - a;
  45. err = (a - (s - bb)) + (b - bb);
  46. return s;
  47. }
  48. /* Computes fl(a-b) and err(a-b). */
  49. inline double two_diff(double a, double b, double &err) {
  50. double s = a - b;
  51. double bb = s - a;
  52. err = (a - (s - bb)) - (b + bb);
  53. return s;
  54. }
  55. #ifndef QD_FMS
  56. /* Computes high word and lo word of a */
  57. inline void split(double a, double &hi, double &lo) {
  58. double temp;
  59. if (a > _QD_SPLIT_THRESH || a < -_QD_SPLIT_THRESH) {
  60. a *= 3.7252902984619140625e-09; // 2^-28
  61. temp = _QD_SPLITTER * a;
  62. hi = temp - (temp - a);
  63. lo = a - hi;
  64. hi *= 268435456.0; // 2^28
  65. lo *= 268435456.0; // 2^28
  66. } else {
  67. temp = _QD_SPLITTER * a;
  68. hi = temp - (temp - a);
  69. lo = a - hi;
  70. }
  71. }
  72. #endif
  73. /* Computes fl(a*b) and err(a*b). */
  74. inline double two_prod(double a, double b, double &err) {
  75. #ifdef QD_FMS
  76. double p = a * b;
  77. err = QD_FMS(a, b, p);
  78. return p;
  79. #else
  80. double a_hi, a_lo, b_hi, b_lo;
  81. double p = a * b;
  82. split(a, a_hi, a_lo);
  83. split(b, b_hi, b_lo);
  84. err = ((a_hi * b_hi - p) + a_hi * b_lo + a_lo * b_hi) + a_lo * b_lo;
  85. return p;
  86. #endif
  87. }
  88. /* Computes fl(a*a) and err(a*a). Faster than the above method. */
  89. inline double two_sqr(double a, double &err) {
  90. #ifdef QD_FMS
  91. double p = a * a;
  92. err = QD_FMS(a, a, p);
  93. return p;
  94. #else
  95. double hi, lo;
  96. double q = a * a;
  97. split(a, hi, lo);
  98. err = ((hi * hi - q) + 2.0 * hi * lo) + lo * lo;
  99. return q;
  100. #endif
  101. }
  102. /* Computes the nearest integer to d. */
  103. inline double nint(double d) {
  104. if (d == std::floor(d))
  105. return d;
  106. return std::floor(d + 0.5);
  107. }
  108. /* Computes the truncated integer. */
  109. inline double aint(double d) {
  110. return (d >= 0.0) ? std::floor(d) : std::ceil(d);
  111. }
  112. /* These are provided to give consistent
  113. interface for double with double-double and quad-double. */
  114. inline void sincosh(double t, double &sinh_t, double &cosh_t) {
  115. sinh_t = std::sinh(t);
  116. cosh_t = std::cosh(t);
  117. }
  118. inline double sqr(double t) {
  119. return t * t;
  120. }
  121. inline double to_double(double a) { return a; }
  122. inline int to_int(double a) { return static_cast<int>(a); }
  123. }
  124. #endif /* _QD_INLINE_H */