Small utilities for big decimal numbers.

Overview

dnum

npm version bundle size License

dnum (Decimal Numbers) is a library that allows to operate on large numbers represented as a pair composed of a BigInt for the value, and a Number for the decimals.

It is not a replacement for libraries such as decimal.js or the native BigInt operators (which it uses internally). Instead, dnum focuses on a small (~1kb) set of utilities focused around the Dnum data structure, allowing to safely operate on numbers represented in various decimal precisions.

The Dnum data structure is a simple array with two entries, or tuple: a BigInt for the value, and a Number for the decimals. This is how it looks in TypeScript:

type Dnum = [value: bigint, decimals: number];

Install

npm install --save dnum
pnpm add dnum
yarn add dnum

Example

dnum can be useful to manipulate different currencies together, so let’s imagine a situation where you have the price of a given token token TKN expressed in ETH, which you received it as a string to avoid any precision issue:

let tknPriceInEth = "17.30624293209842";

And you have the price of ETH in USD, as a number this time:

let ethPriceInUsd = 1002.37;

Finally, you have a certain quantity of TKN to be displayed, as a BigInt:

let tknQuantity = 1401385000000000000000n; // 1401.385 with 18 decimals precision

You want to display the USD value of tknQuantity, which would normally require to:

  • Parse the numbers correctly (without using parseInt() / parseFloat() to avoid precision loss).
  • Convert everything into BigInt values with an identical decimals precision.
  • Multiply the numbers and get the result.
  • Convert it into a string to format it − without using Number since you’d lose precision.

dnum can do all of this for you:

// No need to convert anything, you can just multiply different formats of decimal numbers:
let tknPriceInUsd = dnum.multiply(tknPriceInEth, ethPriceInUsd);

// A Dnum is just a two entries array (or tuple): [value: bigint, decimals: number]
let tknQuantityInUsd = dnum.multiply([tknQuantity, 18], tknPriceInUsd);

dnum.format(tknQuantityInUsd, 2); // $24,310,188.17

You can play with this example on CodeSandbox.

API

Types

type Dnum = [value: bigint, decimals: number];
type Numberish = string | number | bigint | Dnum;

format(value, options)

Formats the number for display purposes.

Name Description Type
value The value to format. Dnum
options.digits Number of digits to display. Setting options to a number acts as an alias for this option. Defaults to the number of decimals in the passed Dnum. number
options.compact Compact formatting (e.g. “1,000” becomes “1K”). object
options.trailingZeros Add trailing zeros if any, following the number of digits. object
returns Formatted string. string

Example

let amount = [123456789000000000000000n, 18];

// If no digits are provided, the digits correspond to the decimals
dnum.format(amount); // 123,456.789

// options.digits
dnum.format(amount, { digits: 2 }); // 123,456.79
dnum.format(amount, 2); // (alias)

// options.compact
dnum.format(amount, { compact: true }); // 123K

// options.trailingZeros
dnum.format(amount, { digits: 6, trailingZeros: true }); // 123,456.789000

from(valueToParse, decimals)

Parse a value and convert it into a Dnum.

Name Description Type
valueToParse Value to convert into a Dnum Numberish
decimals Number of decimals (or true for auto) number | true
returns Converted value Dnum

Example

// Parses a number expressed as a string or number
let amount = dnum.from("17.30624", 18);

// amount equals [17306240000000000000n, 18]

add(value1, value2, decimals)

Adds two values together, regardless of their decimals. decimals correspond to the decimals desired in the result.

Name Description Type
value1 First value to add Numberish
value2 Second value to add Numberish
decimals (optional) Result decimals (defaults to value1 decimals) number
returns Result Dnum

subtract(value1, value2, decimals)

Subtract a value from another one, regardless of their decimals. decimals correspond to the decimals desired in the result.

Name Description Type
value1 First value to add Numberish
value2 Second value to add Numberish
decimals (optional) Result decimals (defaults to value1 decimals) number
returns Result Dnum

Alias: sub()

multiply(value1, value2, decimals)

Multiply two values together, regardless of their decimals. decimals correspond to the decimals desired in the result.

Name Description Type
value1 First value to multiply Numberish
value2 Second value to multiply Numberish
decimals (optional) Result decimals (defaults to value1 decimals) number
returns Result Dnum

Alias: mul()

Example

let ethPriceUsd = [100000n, 2]; // 1000 USD
let tokenPriceEth = [570000000000000000, 18]; // 0.57 ETH

let tokenPriceUsd = dnum.multiply(tokenPriceEth, ethPriceUsd, 2); // 570 USD

// tokenPriceUsd equals [57000, 2]

divide(value1, value2, decimals)

Divide a value by another one, regardless of their decimals. decimals correspond to the decimals desired in the result.

Name Description Type
value1 Dividend Numberish
value2 Divisor Numberish
decimals (optional) Result decimals (defaults to value1 decimals) number
returns Result value Dnum

Alias: div()

Example

let ethPriceUsd = [100000n, 2]; // 1000 USD
let tokenPriceUsd = [57000, 2]; // 570 USD

let tokenPriceEth = dnum.divide(tokenPriceUsd, ethPriceUsd, 18); // 0.57 ETH

// tokenPriceEth equals [570000000000000000, 18]

toJSON(value)

Converts the Dnum data structure into a JSON-compatible string. This function is provided because JSON.stringify() doesn’t work with BigInt data types.

Name Description Type
value The number to convert into a JSON Dnum
returns Result value string
let json = toJSON([123456789000000000000n, 18]);

// json === "[\"123456789000000000000\", 18]";

fromJSON(value)

Converts the string resulting from toJSON() back into a Dnum.

Name Description Type
value The string value to convert back into a Dnum string
returns Result value Dnum
let dnum = fromJSON("[\"123456789000000000000\", 18]");

// dnum === [123456789000000000000n, 18]

setDecimals(value, decimals)

Return a new Dnum with a different amount of decimals. The value will reflect this change so that the represented number stays the same.

Name Description Type
value The number from which decimals will be changed Dnum
decimals New number of decimals number
returns Result value Dnum

Note: from(value, decimals) can also be used instead.

Tree shaking

To make use of tree shaking, named exports are also provided:

import { format, from } from "dnum";

Acknowledgements

You might also like...

Big Chief is a website where you find and share everyday cooking inspiration. Discover recipes, cooks, videos, and how-tos based on the food you love.

Big Chief is a website where you find and share everyday cooking inspiration. Discover recipes, cooks, videos, and how-tos based on the food you love.

Big Chief Big Chief is a website where you find and share everyday cooking inspiration. Discover recipes, cooks, videos, and how-tos based on the food

Jun 1, 2022

WaffleHacks 2022 - Winner of 'Dream Big and Create More Cheers with AB InBev' & Honorable Mention for the Food Insecurity Track

Getting Started with Create React App Welcome to Leftover Marketplace. This is our project for WaffleHacks 2022. Links Presentation and Demo Video Web

Dec 27, 2022

Console app - big float calculator */+-

Интерпритатор математических выражений Изначально для парсинга математических выражений я реализовал алгоритм сортировочной станции, в текущей версии

Jul 16, 2022

A small javascript DOM manipulation library based on Jquery's syntax. Acts as a small utility library with the most common functions.

Quantdom JS Quantdom is a very small (about 600 bytes when ran through terser & gzipped) dom danipulation library that uuses a Jquery like syntax and

Aug 16, 2022

✏️ A small jQuery extension to turn a static HTML table into an editable one. For quickly populating a small table with JSON data, letting the user modify it with validation, and then getting JSON data back out.

jquery-editable-table A small jQuery extension to turn an HTML table editable for fast data entry and validation Demo 👉 https://jsfiddle.net/torrobin

Jul 31, 2022

A CodeMirror (v6) extension for adding relative line numbers to your code editor

Relative Line Numbers for CM6 Installation yarn add codemirror-line-numbers-relative Usage import { EditorView } from "@codemirror/view"; import { Edi

Feb 7, 2022

no-comma is a javascript library for dealing with inputted numbers that include commas

no-comma no-comma is a javascript library for dealing with inputted numbers that include commas. Nocomma will allow you to check if the number contain

Jan 27, 2022

Kyrgyz / Kazakh numbers-to-words converter

Kyrgyz / Kazakh numbers-to-words converter

Mar 12, 2022

🌐 Text Input Component for validating and formatting international phone numbers.

🌐  Text Input Component for validating and formatting international phone numbers.

React Native Intl Phone Field Try the Expo Snack 👏 🕹️ Demo It's a javascript-only (no native code) component that can run in iOS, Android, Expo & Re

Jul 8, 2022
Releases(v2.1.0)
Owner
Pierre Bertet
WWW · OSS · P2P · GUI
Pierre Bertet
A string of four operations of the library, can solve the js digital calculation accuracy of scientific notation and formatting problems, support for thousands of decimal point formatting output operations

A string of four operations of the library, can solve the js digital calculation accuracy of scientific notation and formatting problems, support for thousands of decimal point formatting output operations

null 10 Apr 6, 2022
Hemsida för personer i Sverige som kan och vill erbjuda boende till människor på flykt

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

null 4 May 3, 2022
Kurs-repo för kursen Webbserver och Databaser

Webbserver och databaser This repository is meant for CME students to access exercises and codealongs that happen throughout the course. I hope you wi

null 14 Jan 3, 2023
A small JavaScript library to generate YouTube-like ids from numbers.

Hashids is small JavaScript library to generate YouTube-like ids from numbers. Use it when you don't want to expose your database ids to the user: htt

Bazyli Brzóska 3.9k Dec 30, 2022
A Big Picture, Thesaurus, and Taxonomy of Modern JavaScript Web Development

Spellbook of Modern Web Dev A Big Picture, Thesaurus, and Taxonomy of Modern JavaScript Web Development This document originated from a bunch of most

Dexter Yang 15.6k Dec 31, 2022
Minimalistic portfolio/photography site with masonry grid, page transitions and big images.

Gatsby Starter Portfolio: Emilia Minimalistic portfolio/photography site with masonry grid, page transitions and big images. Themeable with Theme UI.

Cryptob3auty 1 May 20, 2022
Use real-time computing technology and web technology to build a big data Kanban l to solve the problem. Among them, practical technologies include MySQL, Kafka, Flink, Redis, Flask and Echarts

实时计算(English Version) 运用实时计算技术、Web 技术构建一个大数据看板来解决问题。其中实用技术包括Mysql、Kafka、Flink、Redis、Flask和Echarts 目录 1.问题需求 2.方案分析 3.安装环境 4.环境启动命令和运行代码的方法 5.代码目录结构说明

Serendipity 2 Jan 8, 2022
The jQuery Plugin for Big Background Video (and Images)

BigVideo.js ####The jQuery Plugin for Big Background Video (and Images) Learn how to use this plugin on its demo page. 12-30-2015 Update This project

John Polacek 2.3k Jan 9, 2023
An IoT bottle that tracks water consumption. Winner of Best Health Hack, MLH's Best Hardware Hack, and QB3's Best Big Data for the Improvement of Health Care Winner at CruzHacks 2022.

An IoT bottle that tracks water consumption. Winner of Best Health Hack, MLH's Best Hardware Hack, and QB3's Best Big Data for the Improvement of Health Care Winner at CruzHacks 2022.

Nathanael Garza 2 Jan 21, 2022
A little animation for a big menu where the letters of a word shuffle to become the first letter of each menu item.

Letter Shuffle Animation for a Menu A little animation for a big menu where the letters of a word shuffle to become the first letter of each menu item

Codrops 29 Dec 4, 2022