2 double const splitter = 134217729;
5 void fastTwoSumTail(
double const a,
double const b,
double const x,
double& y)
12 void fastTwoSum(
double const a,
double const b,
double& res,
double& err)
15 fastTwoSumTail(a, b, res, err);
19 void fastTwoDiffTail(
double const a,
double const b,
double const x,
double& y)
21 const double bVirt = a - x;
26 void fastTwoDiff(
double a,
double b,
double& res,
double& err)
29 fastTwoDiffTail(a, b, res, err);
33 double twoSumTail(
double const a,
double const b,
double const x)
36 double aVirt = x - bVirt;
43 void twoSum(
double a,
double b,
double& res,
double& err)
46 err = twoSumTail(a, b, res);
50 void twoDiffTail(
double const a,
double const b,
double const x,
double& y)
53 double aVirt = x + bVirt;
60 void twoDiff(
double a,
double b,
double& res,
double& err)
63 twoDiffTail(a, b, res, err);
66 void split(
double num,
double& high,
double& low)
68 double c = splitter * num;
69 double temp = c - num;
75 void twoProductTail(
double const a,
double const b,
double const x,
double& y)
77 double ahi, alo, bhi, blo;
87 void twoProduct(
double a,
double b,
double& res,
double& err)
90 twoProductTail(a, b, res, err);
94 void squareTail(
double const a,
double const x,
double& y)
98 y = x - (high * high);
99 y -= ((high + high) * low);
104 void square(
double num,
double& res,
double& err)
107 squareTail(num, res, err);
110 boost::array<double,3>
twoOneSum(boost::array<double,2>
const& a,
double b)
112 boost::array<double,3> res;
114 twoSum(a[0], b, tmp, res[0]);
115 twoSum(a[1], tmp, res[2], res[1]);
119 boost::array<double,3>
twoOneDiff(boost::array<double,2>
const& a,
double b)
121 boost::array<double,3> res;
124 twoSum(a[1], tmp, res[2], res[1]);
128 vector<double>
twoTwoSum(boost::array<double,2>
const& a, boost::array<double,2>
const& b)
130 vector<double> res(4);
131 double tmp1, tmp2, tmp3;
132 twoSum(a[0], b[0], tmp1, res[0]);
133 twoSum(a[1], tmp1, tmp2, tmp3);
134 twoSum(tmp3, b[1], tmp1, res[1]);
135 twoSum(tmp2, tmp1, res[3], res[2]);
139 vector<double>
twoTwoDiff(boost::array<double,2>
const& a, boost::array<double,2>
const& b)
141 vector<double> res(4);
142 double tmp1, tmp2, tmp3;
143 twoDiff(a[1], b[1], tmp1, res[0]);
144 twoSum(a[0], tmp1, tmp2, tmp3);
145 twoDiff(tmp3, b[0], tmp1, res[1]);
146 twoSum(tmp2, tmp1, res[3], res[2]);
157 for (
size_t i = 0; i < e.size(); ++i)
159 twoSum(R1, e[i], R2, res);
166 if ((R1 != 0.0) || ans.empty())
175 vector<double> temp, ans;
178 double Q, Qnew, current;
181 for (
size_t i = 0; i < e.size(); i++)
183 twoSum(Q, e[i], Qnew, current);
184 temp.push_back(current);
188 for (
size_t i = 1; i < f.size(); i++)
191 for (
size_t j = i; j < temp.size(); j++)
194 twoSum(Q, current, Qnew, temp[j]);
199 for (
size_t i = 0; i < temp.size(); i++)
201 if (fabs(temp[i]) > 0)
203 ans.push_back(temp[i]);
220 unsigned int eIndex, fIndex;
225 if ((fNow > eNow) == (fNow > -eNow))
229 if (eIndex <e.size())
238 if (fIndex <f.size())
243 if ((eIndex < e.size()) && (fIndex < f.size()))
245 if ((fNow > eNow) == (fNow > -eNow))
249 if (eIndex <e.size())
258 if (fIndex <f.size())
268 while ((eIndex < e.size()) && (fIndex <f.size()))
270 if ((fNow > eNow) == (fNow > -eNow))
272 twoSum(Q, eNow, Qnew, hh);
274 if (eIndex < e.size())
281 twoSum(Q, fNow, Qnew, hh);
283 if (fIndex < f.size())
295 while (eIndex < e.size())
297 twoSum(Q, eNow, Qnew, hh);
299 if (eIndex < e.size())
309 while (fIndex < f.size())
311 twoSum(Q, fNow, Qnew, hh);
313 if (fIndex < f.size())
323 if ((Q != 0.0) || ans.empty())
339 double enow = e.front();
340 double fnow = f.front();
343 if ((fnow > enow) == (fnow > -enow))
347 if (eindex < e.size())
356 if (findex < f.size())
361 if ((eindex <e.size()) && ((findex >= f.size()) || ((fnow > enow) == (fnow > -enow))))
365 if (eindex < e.size())
374 if (findex <f.size())
380 for (
size_t count = 2, endp=e.size() + f.size(); count < endp; count++)
382 if ((eindex < e.size()) && ((findex >= f.size()) || ((fnow > enow) == (fnow > -enow))))
386 if (eindex < e.size())
395 if (findex < f.size())
410 if ((Q != 0.0) || ans.empty()) {
422 double product0, product1,sum;
430 int n=
static_cast<int>(e.size());
431 for (eindex = 1; eindex<n; ++eindex)
433 twoProduct(e[static_cast<size_t>(eindex)], b, product1, product0);
434 twoSum(Q, product0,sum, hh);
445 if ((Q != 0.0) || ans.empty()) {
452 vector<double> temp, ans;
455 int bottom =
static_cast<int>(e.size()) - 1;
456 double Q = e[
static_cast<size_t>(bottom)];
457 for (
int eindex =static_cast<int>(e.size()) - 2; eindex >= 0; eindex--)
459 const double enow = e[
static_cast<size_t>(eindex)];
464 temp.insert(temp.begin(), Qnew);
473 for (
size_t i = static_cast<size_t>(bottom) + 1; i <e.size(); i++)
475 const double current = temp[i];
493 for (
size_t i = 1; i < e.size(); i++)
vector< double > expansionSumZeroElim(vector< double > const &e, vector< double > const &f)
Adds up two expansions.
void twoDiff(double a, double b, double &res, double &err)
Difference between two numbers.
boost::array< double, 3 > twoOneSum(boost::array< double, 2 > const &a, double b)
Calculates the sum of a two-expansion and a double.
double estimate(vector< double > const &e)
Calculate a double precision approximation of the expansion.
vector< double > growExpansionZeroElim(vector< double > const &e, double b)
Adds a scalar to an existing expansion.
vector< double > twoTwoSum(boost::array< double, 2 > const &a, boost::array< double, 2 > const &b)
Calculates the sum of two two-expansions.
void twoProduct(double a, double b, double &res, double &err)
Product of two number.
vector< double > compress(vector< double > const &e)
Compresses an expansion.
void twoSum(double a, double b, double &res, double &err)
Calculates the sum of a and b.
void fastTwoDiff(double a, double b, double &res, double &err)
Subtracts two numbers.
boost::array< double, 3 > twoOneDiff(boost::array< double, 2 > const &a, double b)
Calculates the difference between a two-expansion and a double.
vector< double > twoTwoDiff(boost::array< double, 2 > const &a, boost::array< double, 2 > const &b)
Calculates the difference between two two-expansions.
void split(double num, double &high, double &low)
Splits a given number into two, Used for multiplication.
vector< double > fastExpansionSumZeroElim(vector< double > const &e, vector< double > const &f)
Adds up two expansions.
void scaleExpansionZeroElim(vector< double > const &e, double b, vector< double > &result)
Multiplies a scalar by an expansion.
void fastTwoSum(double a, double b, double &res, double &err)
Calculates the sum of two numbers.
vector< double > linearExpansionSumZeroElim(vector< double > const &e, vector< double > const &f)
Adds up two expansions.
void square(double num, double &res, double &err)
Calculates the square of a number.