@numio/bigmath
TypeScript icon, indicating that this package has built-in type declarations

2.2.4 • Public • Published

@numio/bigmath: Precise Arithmetic Beyond JavaScript's Limits

Do you struggle with inaccurate calculations involving very large or very small numbers, or decimal numbers with high precision in JavaScript?

@numio/bigmath is your solution! This library provides a robust set of functions for performing arbitrary-precision arithmetic, effectively overcoming the limitations of JavaScript's built-in Number type. Say goodbye to unexpected rounding errors and precision loss when dealing with numbers that exceed 15 significant digits or involve complex decimal operations.

Why Choose @numio/bigmath?

Solve Precision Problems:

  • Handle Numbers of Any Size: Perform calculations on integers and decimals of virtually unlimited length, without the risk of JavaScript's Number limitations.
  • Eliminate Precision Loss: Achieve accurate results even with numeric literals exceeding 15 significant digits, ensuring the integrity of your calculations.
  • Precise Decimal Operations: Execute addition, subtraction, multiplication, and division on decimal numbers with guaranteed accuracy, including scenarios with negative values.
  • **NEW! Multi-Base Number Support: Seamlessly perform arithmetic operations involving hexadecimal (HEX), octal, binary, and decimal numbers, offering unparalleled flexibility in handling various number formats.
  • **NEW! Number Format Validation: Easily validate if a string represents a valid hexadecimal (isHex), binary (isBinary), decimal (isDecimal), octal (isOctal), or any valid number (isNumber) format supported by the library.

Unlock Advanced Numerical Operations:

  • Control Division Precision: Specify the exact number of digits after the decimal point for division results, with a default precision of 20 digits for high accuracy.

  • Flexible Rounding: Round numbers to the nearest integer or a specific number of decimal places with various rounding modes (up, down, half-up, half-down, half-even, half-odd) to meet your exact requirements.

  • Round Based on Significant Figures: Control rounding based on the number of significant figures, crucial for scientific and engineering applications.

  • Calculate Roots:

    • Calculate Square Root (sqrt): Compute the square root of a number with arbitrary precision. You can also specify the desired precision of the result.
    • **NEW! Calculate Cube Root (cbrt): Determine the cube root of a number with arbitrary precision, allowing you to specify the desired accuracy.
  • Chain Operations with Pipe: Simplify complex calculations by chaining arithmetic operations in a readable and intuitive manner.

  • Analyze Data Distribution:

    • Calculate Quartiles (Q1, Q2, Q3): Understand the spread and central tendency of your numerical data, helping identify outliers and the shape of the distribution.
    • Calculate Median Absolute Deviation (MAD): Measure the dispersion of a dataset, providing a robust alternative to standard deviation that is less sensitive to outliers.
    • Calculate Interquartile Range (IQR): Determine the spread of the middle 50% of your data, useful for identifying the central bulk and potential outliers.
  • Compare Numbers:

    • Check for Equality (isEqual): Accurately determine if two arbitrary-precision numbers are equal.
    • Check if Left is Greater (isLeftGreater): Precisely compare two arbitrary-precision numbers to see if the left operand is greater than the right.
    • **NEW! Check if Left is Greater or Equal (isLeftGreaterOrEqual): Precisely compare two arbitrary-precision numbers to determine if the left operand is greater than or equal to the right.
  • Sort Numbers Accurately: Sort arrays of numbers, including negative and decimal values, in ascending or descending order, correctly handling string representations of numbers that JavaScript's native sort might misinterpret.

  • Calculate Central Tendency: Easily compute the mean (average) of a set of numbers.

  • Identify Extremes: Find the maximum and minimum values within an array of numbers.

  • **NEW! Calculate Absolute Value (abs): Determine the non-negative value of a number, regardless of its sign.

  • **NEW! Convert Number to Another Base (toBase): Seamlessly convert numbers between decimal, hexadecimal (HEX), binary, and octal representations.

When is @numio/bigmath essential?

This library is particularly invaluable in applications where numerical accuracy and the ability to handle large numbers are paramount:

  • Financial Applications: Accurate calculations for large sums of money, precise interest rates, and complex financial modeling.
  • Scientific Computing: Working with extremely large or small numbers in simulations, data analysis, and research.
  • Cryptography: Implementing cryptographic algorithms that rely on high-precision arithmetic.
  • E-commerce and Payments: Handling precise amounts and avoiding rounding errors in transactions.
  • Data Analysis and Statistics: Performing accurate statistical calculations on datasets with varying scales.
  • Low-Level Operations: Working with different number representations commonly found in computer systems.
  • Any Scenario Exceeding JavaScript's Number Limits: Ensuring the reliability of your calculations when dealing with numbers beyond the safe integer limit or requiring more than 15 significant digits.

With @numio/bigmath, you can confidently perform complex arithmetic operations with the assurance of accuracy, regardless of the size or precision of the numbers involved.

Latest update

New Functions added:

  • isHex - Checks if a string is a valid hexadecimal number (prefixed with 0x or -0x).
  • isBinary - Checks if a string is a valid binary number (prefixed with 0b or -0b).
  • isDecimal - Checks if a string is a valid decimal number.
  • isOctal - Checks if a string is a valid octal number (prefixed with 0o or -0o).
  • isNumber - Checks if a string is a valid number in any of the formats supported by the library (decimal, hexadecimal, binary, octal).

Install:

NPM

npm install @numio/bigmath

YARN

yarn add @numio/bigmath

BUN

bun add @numio/bigmath

PNPM

pnpm add @numio/bigmath

DENO

deno add jsr:@numio/bigmath

Examples:

Add numbers

import { add } from "@numio/bigmath";

const int = add(["12345", "99"]); // 12444
const float = add(["0.1", "0.2", "0.3"]); // 0.6
const negative = add(["0.1", "-0.3", "0.1"]); // -0.1

Subtract numbers

import { sub } from "@numio/bigmath";

const int = sub(["150", "99"]); // 51
const float = sub(["1", "0.99"]); // 0.01
const negative = sub(["-0.1", "-0.3", "0.4"]); // -0.2

Multiply numbers

import { mul } from "@numio/bigmath";

const int = mul(["15", "11", "2"]); // 330
const float = mul(["0.01", "0.99"]); // 0.0099
const negative = mul(["-2", "3"]); // -6

Divide numbers

import { div } from "@numio/bigmath";

const int = div(["9999", "33"]); // 303
const float = div(["0.06", "0.2"]); // 0.3
const negative = div(["-2", "-3", "2"]); //0.33333333333333333333

// set number of digit after the decimal. By default it's 20
div(["10", "3"], 4); // 3.3333

HEX, decimal, octal, binary

import { add, sub } from "@numio/bigmath";

add(["0xA", "0x5"]) // HEX + HEX, 10 + 5 = 15
add(["0xA", "2"]) // HEX + decimal, 10 + 2 = 12
sub(["35", "0b11"]) // decimal - binary, 35 - 3 = 32 
sub(["0x1A", "0o31", "0b101", ]) // HEX - octal - binary, 26 - 25 - 5 = -4

Round

import { round } from "@numio/bigmath";

round("-1.12345"); // -1
round("1.5"); // 2
round("1.0"); // 1
round("0.00001"); // 0
round("9.9"); // 10

Round at position

import { round } from "@numio/bigmath";

round("1.12345", { decimals: 1 }); // 1.1
round("1.12345", { decimals: 2 }); // 1.12
round("1.12234", { decimals: 0 }); // 1
round("9.999", { decimals: 2 }); // 10

Round modes

import { round } from "@numio/bigmath";

round("1.11", { decimals: 1, roundMode: "up" }); // 1.2
round("1.19", { decimals: 1, roundMode: "up" }); // 1.2

round("1.11", { decimals: 1, roundMode: "down" }); // 1.1
round("1.19", { decimals: 1, roundMode: "down" }); // 1.1

round("1.15", { decimals: 1, roundMode: "half-up" }); // 1.2
round("1.15", { decimals: 1, roundMode: "half-down" }); // 1.1

round("1.15", { decimals: 1, roundMode: "half-even" }); // 1.2
round("1.25", { decimals: 1, roundMode: "half-even" }); // 1.2
round("1.35", { decimals: 1, roundMode: "half-even" }); // 1.4
round("1.45", { decimals: 1, roundMode: "half-even" }); // 1.4
round("1.55", { decimals: 1, roundMode: "half-even" }); // 1.6

round("1.15", { decimals: 1, roundMode: "half-odd" }); // 1.1
round("1.25", { decimals: 1, roundMode: "half-odd" }); // 1.3
round("1.35", { decimals: 1, roundMode: "half-odd" }); // 1.3
round("1.45", { decimals: 1, roundMode: "half-odd" }); // 1.5
round("1.55", { decimals: 1, roundMode: "half-odd" }); // 1.5

Round with "significant figures" flag

import { round } from "@numio/bigmath";

round("0.000119", { decimals: 2, sigFig: false }); // 0
round("0.000119", { decimals: 2, sigFig: true }); // 0.00012

round("0.0019", { decimals: 1, sigFig: true, roundMode: "down" }); // 0.001
round("0.0011", { decimals: 1, sigFig: true, roundMode: "up" }); // 0.002

round("1.000119", { decimals: 2, sigFig: false }); // 1
round("1.000119", { decimals: 2, sigFig: true }); // 1

Pipe

import { Pipe } from "@numio/bigmath";

const addNums = ["1", "2", "3"];
const subNums = ["0.2", "0.3"];
const divNums = ["4"];
const mulNums = ["2", "5", "0.2"];

new Pipe().add(addNums) // 6
  .div(divNums) // 6 / 4 = 1.5 
  .sub(subNums) // 1.5 - 0.2 - 0.3 = 1
  .mul(mulNums) // 1 * 2 * 5 * 0.2 = 2
  .calc() // convert end result to readable string

new Pipe().sub(["1", "5"]) // 1 - 5 = -4
  .abs() // 4 - returns absolute value

new Pipe().add(["10", "5"]) // 11 + 5 = 15
  .resultToBase(16) // f - returns result converted to base 16

Quartile

import { quartile } from "@numio/bigmath";

quartile(["1", "2", "3", "4", "5", "6", "7", "8", "9"]) // { Q1: "2.5", Q2: "5", Q3: "7.5" }
quartile(["0.001", "0.3", "0.4", "1"]) // { Q1: "0.1505", Q2: "0.35", Q3: "0.7" }

Sort

import { sort } from "@numio/bigmath";

// native js sort for strings
["1", "10", "11", "101", "11", "10", "1"].sort() // ["1", "1", "10", "10", "101", "11", "11"]

// sort from "@numio/bigmath"
sort(["1", "10", "11", "101", "11", "10", "1"]) // ["1", "1", "10", "10", "11", "11", "101"]

// ASC sorting
sort(["-0.1", "0.1", "-1"], "asc") // ["-1", "-0.1", "0.1"]

// DESC sorting
sort(["-0.1", "0.1", "-1"], "desc") // ["0.1", "-0.1", "-1"]

Mean

import { mean } from "@numio/bigmath";

mean(["5", "4", "3", "2", "1", "0"]) // "2.5"
mean(["0.5", "0.4", "0.3", "0.2", "0.1", "0"]) // "0.25"

Max

import { max } from "@numio/bigmath";

max(["2", "-1", "0.1"]) // 2;

Min

import { min } from "@numio/bigmath";

min(["2", "-1", "0.1"]) // -1;

IsEqual

import { isEqual } from "@numio/bigmath";

isEqual({left: "0.1", right: "0.1"}) // true;
isEqual({left: "2", right: "0.1"}) // false;

IsLeftGreater

import { isLeftGreater } from "@numio/bigmath";

isLeftGreater({left: "0.1", right: "2"}) // false;
isLeftGreater({left: "2", right: "0.1"}) // true;
isLeftGreater({left: "0.1", right: "0.1"}) // false;
isLeftGreater({left: "0.1", right: "-0.1"}) // true;

IsLeftGreaterOrEqual

import { isLeftGreaterOrEqual } from "@numio/bigmath";

isLeftGreaterOrEqual({left: "0.1", right: "2"}) // false;
isLeftGreaterOrEqual({left: "2", right: "0.1"}) // true;
isLeftGreaterOrEqual({left: "0.1", right: "0.1"}) // true;
isLeftGreaterOrEqual({left: "0.1", right: "-0.1"}) // true;

MAD - Median Absolute Deviation

import { MAD } from "@numio/bigmath";

MAD(["7", "15", "36", "39", "40", "41"]) // 3;

IQR - Interquartile Range

import { IQR } from "@numio/bigmath";

IQR(["7", "15", "36", "39", "40", "41"]) // 25;

SQRT - square root of a number

import { sqrt } from "@numio/bigmath";

sqrt("81") // 9;
sqrt("3") // 1.7320508075689;

// you can change precision of a result (second parameter), 
sqrt("3", "0.01") // 1.732;
sqrt("3", "0.000000000000000000001") // 1.732050807568877293527;

CBRT - cube root of a number

import { cbrt } from "@numio/bigmath";

cbrt("37") // 3;
cbrt("1000") // 10;
cbrt("15"), // 2.4662120743305

// you can change precision of a result (second parameter), 
cbrt("15", "0.001") // 2.466

ABS - absolute value

import { abs } from "@numio/bigmath";

abs("-1") // 1;
abs("1") // 1;

toBase - convert number to another base

import { toBase } from "@numio/bigmath";

toBase({ value: "11", toBase: 16 }) // b
// 0x - HEX
toBase({ value: "0xb", toBase: 10 }) // 11
// 0b - binary
toBase({ value: "0b101", toBase: 10 }) // 5
toBase({ value: "0b1101", toBase: 16 }) // d
// 0o - octal
toBase({ value: "0o11", toBase: 10 }) // 9

Number format validation

import { isHex, isBinary, isDecimal, isOctal, isNumber } from "@numio/bigmath";

console.log(isHex("0x1A")); // true
console.log(isHex("1A"));    // false (no 0x prefix)
console.log(isHex("-0x2f")); // true
console.log(isHex("0xG"));  // false (invalid hex digit)

console.log(isBinary("0b101")); // true
console.log(isBinary("101"));   // false (no 0b prefix)
console.log(isBinary("-0b11"));  // true
console.log(isBinary("0b12"));  // false (invalid binary digit)

console.log(isDecimal("123"));   // true
console.log(isDecimal("123.45"));// true
console.log(isDecimal("-0.5"));  // true
console.log(isDecimal(".5"));   // false (leading dot)
console.log(isDecimal("10."));  // false (trailing dot)

console.log(isOctal("0o77"));  // true
console.log(isOctal("77"));    // false (no 0o prefix)
console.log(isOctal("-0o12")); // true
console.log(isOctal("0o19"));  // false (invalid octal digit)

console.log(isNumber("0x1A"));  // true (hex)
console.log(isNumber("0b101")); // true (binary)
console.log(isNumber("123.45"));// true (decimal)
console.log(isNumber("0o77"));  // true (octal)
console.log(isNumber("123"));   // true (decimal)
console.log(isNumber("abc"));   // false (not a valid number)

Does not have a limitation on the number of digits. You can use any length you'd like

// NO precision loss using numeric literals with more than 15 significant digits.
const int = add(
  "999999999999999999999999999999999999999999999999999999999999999",
  "2",
); // "1000000000000000000000000000000000000000000000000000000000000001"

const float = mul(
  "0.00000000000000000000000000000000000000000000000000000000000000000009",
  "0.000000002",
); // 0.00000000000000000000000000000000000000000000000000000000000000000000000000018

Download from NPM - https://www.npmjs.com/package/@numio/bigmath

Download from JSR - https://jsr.io/@numio/bigmath

Home page - https://numio.deno.dev

Change log - https://github.com/shpunter/numio-bigmath/blob/main/CHANGELOG.md

License - https://github.com/shpunter/numio-bigmath/blob/main/LICENSE

Package Sidebar

Install

npm i @numio/bigmath

Weekly Downloads

329

Version

2.2.4

License

MIT

Unpacked Size

59.4 kB

Total Files

100

Last publish

Collaborators

  • oleksandr.brudnovskyi