File indexing completed on 2026-08-06 09:31:07
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef _QD_INLINE_H
0016 #define _QD_INLINE_H
0017
0018 #define _QD_SPLITTER 134217729.0
0019 #define _QD_SPLIT_THRESH 6.69692879491417e+299
0020
0021 #ifdef QD_VACPP_BUILTINS_H
0022
0023 #include <builtins.h>
0024 #endif
0025
0026 #include <cmath>
0027 #include <limits>
0028
0029 namespace qd {
0030
0031 static const double _d_nan = std::numeric_limits<double>::quiet_NaN();
0032 static const double _d_inf = std::numeric_limits<double>::infinity();
0033
0034
0035
0036 inline double quick_two_sum(double a, double b, double &err) {
0037 double s = a + b;
0038 err = b - (s - a);
0039 return s;
0040 }
0041
0042
0043 inline double quick_two_diff(double a, double b, double &err) {
0044 double s = a - b;
0045 err = (a - s) - b;
0046 return s;
0047 }
0048
0049
0050 inline double two_sum(double a, double b, double &err) {
0051 double s = a + b;
0052 double bb = s - a;
0053 err = (a - (s - bb)) + (b - bb);
0054 return s;
0055 }
0056
0057
0058 inline double two_diff(double a, double b, double &err) {
0059 double s = a - b;
0060 double bb = s - a;
0061 err = (a - (s - bb)) - (b + bb);
0062 return s;
0063 }
0064
0065 #ifndef QD_FMS
0066
0067 inline void split(double a, double &hi, double &lo) {
0068 double temp;
0069 if (a > _QD_SPLIT_THRESH || a < -_QD_SPLIT_THRESH) {
0070 a *= 3.7252902984619140625e-09;
0071 temp = _QD_SPLITTER * a;
0072 hi = temp - (temp - a);
0073 lo = a - hi;
0074 hi *= 268435456.0;
0075 lo *= 268435456.0;
0076 } else {
0077 temp = _QD_SPLITTER * a;
0078 hi = temp - (temp - a);
0079 lo = a - hi;
0080 }
0081 }
0082 #endif
0083
0084
0085 inline double two_prod(double a, double b, double &err) {
0086 #ifdef QD_FMS
0087 double p = a * b;
0088 err = QD_FMS(a, b, p);
0089 return p;
0090 #else
0091 double a_hi, a_lo, b_hi, b_lo;
0092 double p = a * b;
0093 split(a, a_hi, a_lo);
0094 split(b, b_hi, b_lo);
0095 err = ((a_hi * b_hi - p) + a_hi * b_lo + a_lo * b_hi) + a_lo * b_lo;
0096 return p;
0097 #endif
0098 }
0099
0100
0101 inline double two_sqr(double a, double &err) {
0102 #ifdef QD_FMS
0103 double p = a * a;
0104 err = QD_FMS(a, a, p);
0105 return p;
0106 #else
0107 double hi, lo;
0108 double q = a * a;
0109 split(a, hi, lo);
0110 err = ((hi * hi - q) + 2.0 * hi * lo) + lo * lo;
0111 return q;
0112 #endif
0113 }
0114
0115
0116 inline double nint(double d) {
0117 if (d == std::floor(d))
0118 return d;
0119 return std::floor(d + 0.5);
0120 }
0121
0122
0123 inline double aint(double d) {
0124 return (d >= 0.0) ? std::floor(d) : std::ceil(d);
0125 }
0126
0127
0128
0129 inline void sincosh(double t, double &sinh_t, double &cosh_t) {
0130 sinh_t = std::sinh(t);
0131 cosh_t = std::cosh(t);
0132 }
0133
0134 inline double sqr(double t) {
0135 return t * t;
0136 }
0137
0138 inline double to_double(double a) { return a; }
0139 inline int to_int(double a) { return static_cast<int>(a); }
0140
0141 }
0142
0143 #endif