Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/srknzl/bigdecimal.js

BigInt based BigDecimal implementation
https://github.com/srknzl/bigdecimal.js

arbitrary-precision bigdecimal floating-point math

Last synced: about 2 months ago
JSON representation

BigInt based BigDecimal implementation

Awesome Lists containing this project

README

        

# BigDecimal.js

[![NPM Version][npm-image]][npm-url]
[![NPM Downloads][downloads-image]][downloads-url]
[![codecov](https://codecov.io/gh/srknzl/bigdecimal.js/branch/main/graph/badge.svg?token=Y9PL8TFV2L)](https://codecov.io/gh/srknzl/bigdecimal.js)

[BigInt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt) based BigDecimal implementation for Node.js 10.4 and above.
This implementation is inspired from java BigDecimal class. This implementation is faster than popular big decimal libraries for most operations.
See [benchmarks results part below](https://github.com/srknzl/bigdecimal.js#benchmark-results) for comparison of each operation.

## Advantages of this library

* Faster than other BigDecimal libraries because of native BigInt
* Simple API that is almost same with Java's [BigDecimal](https://docs.oracle.com/en/java/javase/16/docs/api/java.base/java/math/BigDecimal.html)
* No dependencies
* Well tested
* Includes type definition file

## Disadvantages

* This library's minified version is about 5 times larger than big.js's minified version. So the library is not small.

## Installation

```
npm install bigdecimal.js
```

## Usage

* The example usage is given below:

```javascript
// Single unified constructor for multiple values
const { Big } = require('bigdecimal.js');

// Construct from a string and clone it
const x = Big('1.1111111111111111111111');
const y = new Big(x); // you can also use 'new'

const z = x.add(y);
console.log(z.toString()); // 2.2222222222222222222222

// You can also construct from a number or BigInt:
const u = Big(1.1);
const v = Big(2n);

console.log(u.toString()); // 1.1
console.log(v.toString()); // 2
```

You can use MathContext to set precision and rounding mode for a specific operation:

```javascript
const { Big, MC, RoundingMode } = require('bigdecimal.js');

const x = Big('1');
const y = Big('3');

// MC is MathContext constructor that can be used with or without `new`
const res1 = x.divideWithMathContext(y, MC(3));
console.log(res1.toString()); // 0.333

const res2 = x.divideWithMathContext(y, new MC(3, RoundingMode.UP));
console.log(res2.toString()); // 0.334

try {
x.divide(y);
// throws since full precision is requested but it is not possible
} catch (e) {
console.log(e); // RangeError: Non-terminating decimal expansion; no exact representable decimal result.
}
```
## Documentation

* [API Documentation](https://srknzl.github.io/bigdecimal.js)

## Testing

* Install dependencies: `npm i`
* Compile: `npm run compile`
* Run tests: `npm test`

## Running Benchmarks

There is a benchmark suite that compares

* This library
* [big.js](https://github.com/MikeMcl/big.js)
* [bigdecimal](https://github.com/iriscouch/bigdecimal.js)
* [bignumber.js](https://github.com/MikeMcl/bignumber.js)
* [decimal.js](https://github.com/MikeMcl/decimal.js)

To run the benchmark run `npm install` and then `npm run benchmark`.

## Benchmark Results

For now, benchmarked against [big.js](https://www.npmjs.com/package/big.js) and [bigdecimal](https://www.npmjs.com/package/bigdecimal).

* Test Machine:
* M1 2021 MacBook Air
* 16 GB Ram
* MacOS Sonoma 14.2.1
* Update Date: January 28th 2024
* Library versions used:
* big.js 6.2.1
* (this library) bigdecimal.js 1.3.1
* bigdecimal 0.6.1
* bignumber.js: 9.1.2
* decimal.js:10.4.3

* Each operation is run with fixed set of decimal numbers composed of both simple and complex numbers.
* Micro benchmark framework used is [benchmark](https://www.npmjs.com/package/benchmark). Check out [benchmarks folder](https://github.com/srknzl/bigdecimal.js/tree/main/benchmarks) for source code of benchmarks.
* For now, benchmarked the following operations, more operations will be added later.
* Operations per second(op/s):

| Operation | Bigdecimal.js | Big.js | BigNumber.js | decimal.js | GWTBased |
| --- | --- | --- | --- | --- | --- |
| Constructor | 43,962 ( - ) | 38,238 (-13%) | 42,337 (-4%) | 42,355 (-4%) | 2,818 (-94%) |
| Add | 80,569 ( - ) | 18,406 (-77%) | 100,734 (**+25%**) | 59,815 (-26%) | 90 (-100%) |
| Subtract | 73,518 ( - ) | 18,265 (-75%) | 96,022 (**+31%**) | 57,130 (-22%) | 89 (-100%) |
| Multiply | 493,291 ( - ) | 33,422 (-93%) | 26,810 (-95%) | 79,995 (-84%) | 2,609 (-99%) |
| Divide | 15,341 ( - ) | 1,129 (-93%) | 11,721 (-24%) | 13,301 (-13%) | 645 (-96%) |
| Remainder | 9,362 ( - ) | 3,816 (-59%) | 13,470 (**+44%**) | 21,952 (**+134%**) | 2,445 (-74%) |
| Positive pow | 27,403 ( - ) | 25 (-100%) | 113 (-100%) | 3,535 (-87%) | 6 (-100%) |
| Negative pow | 4,863 ( - ) | 21 (-100%) | 109 (-98%) | 1,970 (-59%) | 264 (-95%) |
| Abs | 782,251 ( - ) | 1,424,376 (**+82%**) | 917,526 (**+17%**) | 358,678 (-54%) | 14,132 (-98%) |
| Compare | 546,243 ( - ) | 1,216,388 (**+123%**) | 783,432 (**+43%**) | 417,873 (-24%) | 990,187 (**+81%**) |

[npm-image]: https://img.shields.io/npm/v/bigdecimal.js.svg
[npm-url]: https://npmjs.org/package/bigdecimal.js
[downloads-image]: https://img.shields.io/npm/dm/bigdecimal.js.svg
[downloads-url]: https://npmcharts.com/compare/bigdecimal.js?minimal=true