JSPM

  • Created
  • Published
  • Downloads 74
  • Score
    100M100P100Q68982F
  • License MIT

Floating point expansions with 31 accurate decimal digits (100+ bits), also known as double-word arithmetic

Package Exports

  • double.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (double.js) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

double.js

bundlephobia Build Status Codecov

Floating point expansions with 31 accurate decimal digits (100+ bits), also known as double-word arithmetic. This library can be useful for fast calculation with extended precision. For example in computational geometry and numerically unstable algorithms such as performing triangulation, polygon clipping, inverting matrix and finding differentials.

Algorithm

Number stored as unevaluated sum of two javascript float numbers and uses error-free arithmetic algorithms from references below. This brings accuracy and significant increase in performance in comparison to digit-wise approach, because this float arithmetic is implemented in hardware. Note that there are no theoretical limitations to javascript language since ECMAScript uses 64 bit IEEE 754 with round-to-nearest-even after each operation and without FMA.

Benchmark

You can check quality and time of different libraries in your browser.

Usage

Include double.js script to webpage or install npm package. Almost all arithmetic function named similar to WASM.

// example with ES6 modules
import { Double } from 'double.js';

// classic test: '0.3' - '0.1' == 0.2
console.log(new Double('0.3').sub(new Double('0.1')).toNumber());

// L = sqrt(a^2 + 10)
let L = a.sqr().add(10).sqrt();

// S(r) = 4/3 * PI * r^3
const S = (r) => new Double('4.1887902047863909846168578443726').mul(r.pown(3));

// f'(x) = (f(x+h) - f(x)) / h;
let dF = (x) => F(x.add(h)).sub(F(x)).div(h);

// |f'(x)| < 1 ? print(x)
if (dF(x).abs().lt(1)) { console.log(x.toExponential()); }

You can play with library in sandbox. API details you can find in wiki page. Be careful when initializing a new floats, for example new Double(0.1) is ok only for integer numbers and you should use new Double('0.1') to get correct results. All double-word arithmetic functions are accurate and tested, say me if you find something strange.

Special thanks

To Jeffrey Sarnoff for help me with books and algorithms.

References

  1. J.-M. Muller, etc. Tight and rigourous error bounds for basic building blocks of double-word arithmetic., 2017. [PDF]
  2. J.-M. Muller, N. Brisebarre, F. deDinechin, etc. Handbook of Floating-Point Arithmetic, Chapter 14, 2010.
  3. Theodorus Dekker. A floating-point technique for extending the available precision, 1971. [Viewer]
  4. Yozo Hida, Xiaoye Li, David Bailey. Library for Double-Double and Quad-Double Arithmetic, 2000. [PDF]
  5. Christoph Lauter Basic building blocks for a triple-double intermediate format, 2006. [PDF]

[//]: #(Arithmetic Algorithms for Extended Precision Using Floating-Point Expansions, 2016. http://perso.ens-lyon.fr/jean-michel.muller/07118139.pdf) [//]: #(A new multiplication algorithm for extended precision using floating-point expansions http://perso.ens-lyon.fr/jean-michel.muller/Expansions_ARITH_23.pdf) [//]: #(Ultimately Fast Accurate Summation http://www.ti3.tu-harburg.de/paper/rump/Ru08b.pdf)