Package Exports
- double-double
Readme
Pure double & double-double floating point arithmetic functions with strict error bounds
Documentation
Overview
- Double-double precision floating point operators (similar to quad precision)
- Each function documents a strict error bound (see research [1] below)
- Optimized for speed (see benchmark below)
- Operators include: +, -, *, /, β, abs, <, >, ===, min, max, etc.
- Operators mixing double and double-doubles are also included, e.g.
ddAddDouble
(for adding a double to a double-double) - Error free double precision operators also included, e.g.
twoProduct
(for calculating the exact result of multiplying to doubles) - No classes β a double-double is simply a length 2
Number
array, e.g.
import { twoSum } from 'double-double';
// Specified directly (low order double first)
const a = [-4.357806199228875e-10, 11_638_607.274152497];
// ...or more usually from an earlier calculation
const b = twoSum(213.456, 111.111); // => [-1.4210854715202004e-14, 324.567] (completely error-free)
- All functions are pure, e.g.
// using `a` and `b` as defined above (ddAddDd => double-double + double-double)
const c = ddAddDd(a,b); // => [-2.42072459299969e-10, 11638931.841152497]
- No dependencies
Installation
npm install double-double
This package is ESM only
and can be used in Node.js
(or in a browser when bundled using e.g. Webpack).
Additionally, self-contained ECMAScript Module
(ESM) files index.module.js
and
index.module.min.js
in the ./browser
folder is provided.
Or, if you need a legacy browser script there is also index.js
and index.min.js
in the ./browser
folder. Either script exposes a global
variable called doubleDouble
.
See full examples below.
Usage
Node.js
// @filename: `test.mjs` (or `test.js` if { "type": "module" } is specified in your package.json)
import { ddAddDd } from 'double-double'; // `ddAddDd` returns the sum of two double-doubles
const dd1 = [-4.357806199228875e-10, 11638607.274152497]; // some double-double
const dd2 = [4.511949494578893e-11, -2797357.2918064594]; // another double-double
const r1 = ddAddDd(dd1,dd2); // sum the two double-doubles
const r2 = [-3.906611249770986e-10, 8841249.982346037]; // the correct result
if (r1[0] === r2[0] && r1[1] === r2[1]) {
console.log('success! π'); // we should get to here!
} else {
console.log('failure! π₯'); // ...and not here
}
Browsers - ESM - (Chrome 61+, Safari 11+, Firefox 60+, Opera 48+, Edge 16+, Internet Explorer)
<!doctype html>
<html lang="en">
<head>
<script type="module">
import { ddAddDd } from "./node_modules/double-double/browser/index.module.min.js";
const dd1 = [-4.357806199228875e-10, 11638607.274152497]; // some double-double
const dd2 = [4.511949494578893e-11, -2797357.2918064594]; // another double-double
const r1 = ddAddDd(dd1,dd2); // sum the two double-doubles
const r2 = [-3.906611249770986e-10, 8841249.982346037]; // the correct result
if (r1[0] === r2[0] && r1[1] === r2[1]) {
console.log('success! π'); // we should get to here!
} else {
console.log('failure! π₯'); // ...and not here
}
</script>
</head>
<body>Check the console.</body>
</html>
Browsers (older) - Legacy Scripts
<!doctype html>
<html lang="en">
<head>
<script src="./browser/index.min.js"></script>
<script>
const { ddAddDd } = doubleDouble;
const dd1 = [-4.357806199228875e-10, 11638607.274152497]; // some double-double
const dd2 = [4.511949494578893e-11, -2797357.2918064594]; // another double-double
const r1 = ddAddDd(dd1,dd2); // sum the two double-doubles
const r2 = [-3.906611249770986e-10, 8841249.982346037]; // the correct result
if (r1[0] === r2[0] && r1[1] === r2[1]) {
console.log('success! π'); // we should get to here!
} else {
console.log('failure! π₯'); // ...and not here
}
</script>
</head>
<body>Check the console.</body>
</html>
Bundlers (Webpack, Rollup, ...)
Webpack will be taken as an example here.
Since your webpack config file might still use CommonJS
you must rename
webpack.config.js
to webpack.config.cjs
.
If you are using TypeScript:
Since this is an ESM only
library you must use resolve-typescript-plugin
(at least until webpack catches up with ESM?) in your webpack.config.cjs
file.
npm install --save-dev resolve-typescript-plugin
and follow the instructions given at resolve-typescript-plugin.
Additionally, follow this guide.
βImportantβ
When using bundlers:
import { operators } from 'double-double'and then later in the code get the functions you need, e.g.:
const { ddAddDd as add, twoProduct, /* etc. */ } = operators;as opposed to importing the operators directly.
This will increase performance roughly 5 times!
Why? Because Webpack (and Rollup) exports functions using getters that gets invoked on every function call adding a big overhead and slowing down each function. This is not an issue if the code is not bundled, e.g. when using Node.js.
Research
The following research / books / lectures have been used or are directly relevant to this library (especially the first two):
- Mioara Joldes, Jean-Michel Muller, Valentina Popescu, Tight and rigourous error bounds for basic building blocks of double-word arithmetic
- T. J. Dekker, A Floating-Point Technique for Extending the Available Precision
- Yozo Hida, Xiaoye S. Li, David H. Bailey, Library for Double-Double and Quad-Double Arithmetic
- Nicholas J. Higham, Accuracy and Stability of Numerical Algorithms
Benchmark
Similar libraries
License
MIT