UNPKG

quaeratin

Version:

An extended precision floating point library (as per Shewchuk) - precision only limited by overflow / underflow

170 lines 5.56 kB
import { twoProduct } from '../basic/two-product.js'; import { twoSum } from '../basic/two-sum.js'; import { fastTwoSum } from '../basic/fast-two-sum.js'; import { eCompress } from './e-compress.js'; const f = 134217729; // 2**27 + 1; // We *have* to do the below❗ The assignee is a getter❗ The assigned is a pure function❗ const tp = twoProduct; const ts = twoSum; const fts = fastTwoSum; const compress = eCompress; /** * Returns the result of multiplying an expansion by a double. * * * see [Shewchuk](https://people.eecs.berkeley.edu/~jrs/papers/robustr.pdf) * * Theorem 19 (Shwechuk): Let e = sum_(i=1)^m(e_i) be a nonoverlapping expansion * of m p-bit components, and const b be a p-bit value where p >= 4. Suppose that * the components of e are sorted in order of increasing magnitude, except that * any of the e_i may be zero. Then the following algorithm will produce a * nonoverlapping expansion h such that h = sum_(i=1)^(2m)(h_i) = be, where the * components of h are also in order of increasing magnitude, except that any of * the h_i may be zero. Furthermore, if e is nonadjacent and round-to-even * tiebreaking is used, then h is non-adjacent. * * @param e a double floating point expansion * @param b a double */ function scaleExpansion(e, b) { const m = e.length; //const h: number[] = new Array(2*m); let q_; //[h[0], q] = tp(e[0], b); // inlined (above line) const a = e[0]; let q = a * b; const c = f * a; const ah = c - (c - a); const al = a - ah; const d = f * b; const bh = d - (d - b); const bl = b - bh; const h = []; //h[0] = (al*bl) - ((q - (ah*bh)) - (al*bh) - (ah*bl)); const hh = (al * bl) - ((q - (ah * bh)) - (al * bh) - (ah * bl)); if (hh !== 0) { h.push(hh); } for (let i = 1; i < m; i++) { //const [t, T] = tp(e[i], b); // inlined (above line) const a = e[i]; const T = a * b; const c = f * a; const ah = c - (c - a); const al = a - ah; const d = f * b; const bh = d - (d - b); const bl = b - bh; const t = (al * bl) - ((T - (ah * bh)) - (al * bh) - (ah * bl)); //[h[2*i-1], q_] = ts(q, t); // inlined (above line) const x = q + t; const bv = x - q; //h[2*i-1] = (q - (x - bv)) + (t - bv); //h.push((q - (x - bv)) + (t - bv)); const hh = (q - (x - bv)) + (t - bv); if (hh !== 0) { h.push(hh); } q_ = x; //[h[2*i], q] = fts(T, q_); // inlined (above line) const xx = T + q_; //h[2*i] = q_ - (xx - T); //h.push(q_ - (xx - T)); const hhh = q_ - (xx - T); if (hhh !== 0) { h.push(hhh); } q = xx; } //h[2*m - 1] = q; //h.push(q); if (q !== 0 || h.length === 0) { h.push(q); } //return eCompress(h); return h; } /** * Returns the result of multiplying an expansion by a double. * * * see [Shewchuk](https://people.eecs.berkeley.edu/~jrs/papers/robustr.pdf) * * Theorem 19 (Shwechuk): Let e = sum_(i=1)^m(e_i) be a nonoverlapping expansion * of m p-bit components, and const b be a p-bit value where p >= 4. Suppose that * the components of e are sorted in order of increasing magnitude, except that * any of the e_i may be zero. Then the following algorithm will produce a * nonoverlapping expansion h such that h = sum_(i=1)^(2m)(h_i) = be, where the * components of h are also in order of increasing magnitude, except that any of * the h_i may be zero. Furthermore, if e is nonadjacent and round-to-even * tiebreaking is used, then h is non-adjacent. * * @param e a double floating point expansion * @param b a double */ function scaleExpansion2(b, e) { const m = e.length; //const h: number[] = new Array(2*m); let q_; //[h[0], q] = tp(e[0], b); // inlined (above line) const a = e[0]; let q = a * b; const c = f * a; const ah = c - (c - a); const al = a - ah; const d = f * b; const bh = d - (d - b); const bl = b - bh; const h = []; //h[0] = (al*bl) - ((q - (ah*bh)) - (al*bh) - (ah*bl)); const hh = (al * bl) - ((q - (ah * bh)) - (al * bh) - (ah * bl)); if (hh !== 0) { h.push(hh); } for (let i = 1; i < m; i++) { //const [t, T] = tp(e[i], b); // inlined (above line) const a = e[i]; const T = a * b; const c = f * a; const ah = c - (c - a); const al = a - ah; const d = f * b; const bh = d - (d - b); const bl = b - bh; const t = (al * bl) - ((T - (ah * bh)) - (al * bh) - (ah * bl)); //[h[2*i-1], q_] = ts(q, t); // inlined (above line) const x = q + t; const bv = x - q; //h[2*i-1] = (q - (x - bv)) + (t - bv); //h.push((q - (x - bv)) + (t - bv)); const hh = (q - (x - bv)) + (t - bv); if (hh !== 0) { h.push(hh); } q_ = x; //[h[2*i], q] = fts(T, q_); // inlined (above line) const xx = T + q_; //h[2*i] = q_ - (xx - T); //h.push(q_ - (xx - T)); const hhh = q_ - (xx - T); if (hhh !== 0) { h.push(hhh); } q = xx; } //h[2*m - 1] = q; //h.push(q); if (q !== 0 || h.length === 0) { h.push(q); } //return eCompress(h); return h; } export { scaleExpansion, scaleExpansion2 }; //# sourceMappingURL=scale-expansion.js.map