big.js vs bignumber.js vs decimal.js vs mathjs
Arbitrary-Precision Arithmetic Libraries for JavaScript
big.jsbignumber.jsdecimal.jsmathjsSimilar Packages:

Arbitrary-Precision Arithmetic Libraries for JavaScript

JavaScript numbers follow the IEEE 754 standard, which causes rounding errors in basic decimal math like 0.1 + 0.2. These libraries provide arbitrary-precision decimal types to ensure accuracy in financial, scientific, and commercial applications. big.js, bignumber.js, and decimal.js focus specifically on precise decimal arithmetic, while mathjs offers a broader math engine with big number support included.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
big.js05,17258.9 kB9a year agoMIT
bignumber.js06,999499 kB415 days agoMIT
decimal.js07,182284 kB2010 months agoMIT
mathjs015,0289.43 MB181a month agoApache-2.0

Arbitrary-Precision Arithmetic: big.js vs bignumber.js vs decimal.js vs mathjs

JavaScript numbers are based on the IEEE 754 standard for floating-point arithmetic. This causes well-known errors like 0.1 + 0.2 resulting in 0.30000000000000004. For financial apps, scientific tools, or any system requiring exact decimal math, native numbers are not safe. The libraries big.js, bignumber.js, decimal.js, and mathjs solve this by implementing arbitrary-precision decimal types. Let's compare how they handle real-world engineering tasks.

🏗️ Initialization and Setup

Each library has its own constructor and configuration style. Some allow global settings, while others rely on instance methods.

big.js uses a simple constructor and allows global configuration for precision.

import Big from 'big.js';

// Configure global precision
Big.DP = 20;
Big.RM = 1;

const value = new Big('123.456');

bignumber.js offers a constructor that accepts numbers, strings, or other BigNumber instances.

import BigNumber from 'bignumber.js';

// Configure globally
BigNumber.config({ DECIMAL_PLACES: 20 });

const value = new BigNumber('123.456');

decimal.js uses a similar constructor but supports more advanced configuration options out of the box.

import Decimal from 'decimal.js';

// Configure globally
Decimal.set({ precision: 20 });

const value = new Decimal('123.456');

mathjs requires creating an instance or importing the main object, often with custom configuration for number types.

import math from 'mathjs';

// Create a bignumber directly
const value = math.bignumber('123.456');

// Or configure the default number type
const customMath = math.create({ number: 'BigNumber' });

➕ Basic Arithmetic Operations

All four libraries support standard arithmetic, but the method names and chaining styles differ slightly.

big.js uses method chaining for operations like plus, minus, times, and div.

import Big from 'big.js';

const x = new Big('10');
const y = new Big('0.1');

const sum = x.plus(y);
const product = x.times(y);

bignumber.js provides similar methods with support for multiple arguments in some cases.

import BigNumber from 'bignumber.js';

const x = new BigNumber('10');
const y = new BigNumber('0.1');

const sum = x.plus(y);
const product = x.multipliedBy(y);

decimal.js supports method chaining and allows passing values directly without wrapping them first.

import Decimal from 'decimal.js';

const x = new Decimal('10');
const y = '0.1';

const sum = x.plus(y);
const product = x.times(y);

mathjs uses functional methods rather than chaining, which can feel different for OOP developers.

import math from 'mathjs';

const x = math.bignumber('10');
const y = math.bignumber('0.1');

const sum = math.add(x, y);
const product = math.multiply(x, y);

🧮 Advanced Mathematical Functions

Not all libraries support advanced operations like powers, square roots, or trigonometry. This is a key differentiator.

big.js is limited to basic arithmetic. It does not support square roots or powers beyond integers.

import Big from 'big.js';

const x = new Big('4');
// x.sqrt() is NOT available in big.js
// You must use another library for advanced math

bignumber.js includes square roots and integer powers, covering most common needs.

import BigNumber from 'bignumber.js';

const x = new BigNumber('4');
const root = x.sqrt(); // Returns 2
const pow = x.pow(3);  // Returns 8

decimal.js supports non-integer exponents and a wider range of math functions.

import Decimal from 'decimal.js';

const x = new Decimal('4');
const root = x.sqrt();      // Returns 2
const pow = x.pow(1.5);     // Returns 8 (supports non-integer)
const sin = x.sin();        // Trigonometry supported

mathjs provides the most extensive set of functions, including units and matrices.

import math from 'mathjs';

const x = math.bignumber('4');
const root = math.sqrt(x);
const pow = math.pow(x, 1.5);
const sin = math.sin(x);

📝 Expression Parsing and Evaluation

Only one of these libraries is designed to parse and evaluate mathematical strings directly.

big.js does not support expression parsing. You must manually chain operations.

import Big from 'big.js';

// Manual chaining required
const result = new Big('10').plus('20').times('2');

bignumber.js also requires manual chaining or separate function calls.

import BigNumber from 'bignumber.js';

// Manual chaining required
const result = new BigNumber('10').plus('20').multipliedBy('2');

decimal.js focuses on object methods rather than string evaluation.

import Decimal from 'decimal.js';

// Manual chaining required
const result = new Decimal('10').plus('20').times('2');

mathjs excels here with a powerful expression parser for dynamic formulas.

import math from 'mathjs';

// Evaluate string expressions directly
const result = math.evaluate('10 + 20 * 2');

// With variables
const scope = { a: 10, b: 20 };
const resultWithVars = math.evaluate('a + b * 2', scope);

⚙️ Configuration and Precision Control

Managing rounding and precision is critical for financial consistency.

big.js uses static properties for global configuration.

import Big from 'big.js';

Big.DP = 2; // Decimal places
Big.RM = 0; // Rounding mode

const val = new Big('1.235').toFixed(); // '1.24'

bignumber.js uses a configuration object for more detailed control.

import BigNumber from 'bignumber.js';

BigNumber.config({
  DECIMAL_PLACES: 2,
  ROUNDING_MODE: BigNumber.ROUND_HALF_UP
});

const val = new BigNumber('1.235').toFixed(); // '1.24'

decimal.js offers similar configuration but with more options for edge cases.

import Decimal from 'decimal.js';

Decimal.set({
  precision: 20,
  rounding: Decimal.ROUND_HALF_UP
});

const val = new Decimal('1.235').toDecimalPlaces(2); // '1.24'

mathjs handles configuration through the create method or global settings.

import math from 'mathjs';

math.config({
  precision: 20,
  number: 'BigNumber'
});

const val = math.bignumber('1.235').toFixed(2); // '1.24'

📊 Summary Table

Featurebig.jsbignumber.jsdecimal.jsmathjs
Primary UseBasic FinanceGeneral PrecisionAdvanced DecimalFull Math Engine
Bundle SizeSmallMediumMediumLarge
API StyleChainingChainingChainingFunctional
Expression Parse
Trigonometry
Non-Int Pow

💡 Final Recommendation

big.js is the lightweight choice for simple currency math where bundle size is a concern. It does one job and does it well without extra features.

bignumber.js is the balanced option for most web apps. It has strong community support and handles standard precision needs reliably.

decimal.js is the robust choice for complex decimal logic. Use it when you need non-integer powers or stricter decimal compliance.

mathjs is the powerhouse for scientific or dynamic apps. Choose it if you need expression parsing, units, or matrices alongside big numbers.

Final Thought: All four libraries solve the floating-point problem effectively. The decision comes down to feature needs and bundle cost. For most financial frontends, bignumber.js or decimal.js offers the best balance of safety and usability.

How to Choose: big.js vs bignumber.js vs decimal.js vs mathjs

  • big.js:

    Choose big.js if you need a lightweight solution for basic financial calculations like addition and multiplication. It has a smaller footprint than the others but lacks advanced features like square roots or non-integer powers. This package is ideal for projects where bundle size matters and math requirements are simple.

  • bignumber.js:

    Choose bignumber.js if you want a balanced library with wide community adoption and solid documentation. It handles most decimal arithmetic needs well and supports configuration for precision and rounding modes. This is a safe default for general-purpose precision work without the overhead of a full math engine.

  • decimal.js:

    Choose decimal.js if your application requires complex decimal operations like non-integer exponents or higher precision guarantees. It is designed to be more robust than bignumber.js for edge cases involving decimal floating point arithmetic. Use this when accuracy is the top priority and you need advanced mathematical functions.

  • mathjs:

    Choose mathjs if you need a complete math engine that handles units, matrices, and expression parsing alongside big numbers. It is much larger than the others but provides powerful tools like evaluate for string-based math expressions. This fits projects requiring scientific calculations or dynamic formula evaluation.

README for big.js

big.js

A small, fast JavaScript library for arbitrary-precision decimal arithmetic.

npm version npm downloads CI

Features

  • Simple API
  • Faster, smaller and easier-to-use than JavaScript versions of Java's BigDecimal
  • Only 6 KB minified
  • Replicates the toExponential, toFixed and toPrecision methods of JavaScript Numbers
  • Stores values in an accessible decimal floating point format
  • Comprehensive documentation and test set
  • No dependencies
  • Uses ECMAScript 3 only, so works in all browsers

The little sister to bignumber.js and decimal.js. See here for some notes on the difference between them.

Install

The library is the single JavaScript file big.js or the ES module big.mjs.

Browsers

Add Big to global scope:

<script src='path/to/big.js'></script>

ES module:

<script type='module'>
import Big from './path/to/big.mjs';

Get a minified version from a CDN:

<script src='https://cdn.jsdelivr.net/npm/big.js@7.0.1/big.min.js'></script>

Node.js

$ npm install big.js

CommonJS:

const Big = require('big.js');

ES module:

import Big from 'big.js';

Deno

import Big from 'https://raw.githubusercontent.com/mikemcl/big.js/v7.0.1/big.mjs';
import Big from 'https://unpkg.com/big.js@latest/big.mjs';

Use

In the code examples below, semicolons and toString calls are not shown.

The library exports a single constructor function, Big.

A Big number is created from a primitive number, string, or other Big number.

x = new Big(123.4567)
y = Big('123456.7e-3')                 // 'new' is optional
z = new Big(x)
x.eq(y) && x.eq(z) && y.eq(z)          // true

In Big strict mode, creating a Big number from a primitive number is disallowed.

Big.strict = true
x = new Big(1)                         // TypeError: [big.js] Invalid number
y = new Big('1.0000000000000001')
y.toNumber()                           // Error: [big.js] Imprecise conversion

A Big number is immutable in the sense that it is not changed by its methods.

0.3 - 0.1                              // 0.19999999999999998
x = new Big(0.3)
x.minus(0.1)                           // "0.2"
x                                      // "0.3"

The methods that return a Big number can be chained.

x.div(y).plus(z).times(9).minus('1.234567801234567e+8').plus(976.54321).div('2598.11772')
x.sqrt().div(y).pow(3).gt(y.mod(z))    // true

Like JavaScript's Number type, there are toExponential, toFixed and toPrecision methods.

x = new Big(255.5)
x.toExponential(5)                     // "2.55500e+2"
x.toFixed(5)                           // "255.50000"
x.toPrecision(5)                       // "255.50"

The arithmetic methods always return the exact result except div, sqrt and pow (with negative exponent), as these methods involve division.

The maximum number of decimal places and the rounding mode used to round the results of these methods is determined by the value of the DP and RM properties of the Big number constructor.

Big.DP = 10
Big.RM = Big.roundHalfUp

x = new Big(2);
y = new Big(3);
z = x.div(y)                           // "0.6666666667"
z.sqrt()                               // "0.8164965809"
z.pow(-3)                              // "3.3749999995"
z.times(z)                             // "0.44444444448888888889"
z.times(z).round(10)                   // "0.4444444445"

The value of a Big number is stored in a decimal floating point format in terms of a coefficient, exponent and sign.

x = new Big(-123.456);
x.c                                    // [1,2,3,4,5,6]    coefficient (i.e. significand)
x.e                                    // 2                exponent
x.s                                    // -1               sign

For advanced usage, multiple Big number constructors can be created, each with an independent configuration.

For further information see the API reference documentation.

Minify

To minify using, for example, npm and terser

$ npm install -g terser
$ terser big.js -c -m -o big.min.js

Test

The test directory contains the test scripts for each Big number method.

The tests can be run with Node.js or a browser.

Run all the tests:

$ npm test

Test a single method:

$ node test/toFixed

For the browser, see runner.html and test.html in the test/browser directory.

big-vs-number.html is a old application that enables some of the methods of big.js to be compared with those of JavaScript's Number type.

TypeScript

The DefinitelyTyped project has a Typescript type definitions file for big.js.

$ npm install --save-dev @types/big.js

Any questions about the TypeScript type definitions file should be addressed to the DefinitelyTyped project.

Licence

MIT

Contributors

Financial supporters

Thank you to all who have supported this project via Open Collective, particularly Coinbase.