dnum

repository·main·Indexed 43 days ago

https://github.com/bpierre/dnum

A lightweight library (v2.17.0) for manipulating large decimal numbers using a value + decimals pair structure (Dnum) to prevent precision loss. It provides utilities for creation, arithmetic (add, subtract, multiply, divide, remainder), comparison, rounding, and human-readable formatting with support for compact notation and localization.

Tokens
6.1K
Snippets
31
Records
33
Agent score
50%

What's inside dnum

  1. Understand the Dnum data structure

    main

    In dnum, numbers are represented as a Dnum type, which is a tuple consisting of a bigint value and a number representing decimal precision. This structure allows you to maintain high precision for large numbers while offering flexibility for mathematical operations and formatting.

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

    type Dnum = [value: bigint, decimals: number];
    
    // Example of a Dnum value representing 2 followed by 18 decimals
    let a: Dnum = [2000000000000000000n, 18];
  2. When to use dnum vs BigInt or decimal.js

    main

    dnum is not a full replacement for heavy-duty libraries like decimal.js or the native BigInt.

    Use dnum when you need a lightweight (~1kb) set of utilities to safely manipulate numbers represented in various decimal precisions using the Dnum data structure. It is optimized for simplicity and small footprint rather than providing a comprehensive mathematical suite.

  3. Understand Dnum and Numberish types

    main

    The core data structure in dnum is Dnum, which represents a large decimal number as a tuple containing a bigint value and a number representing the decimal places.

    Numberish is a type alias that allows you to pass various formats into most dnum functions, including strings, numbers, bigints, or existing Dnum tuples.

    type Dnum = [value: bigint, decimals: number];
    type Numberish = string | number | bigint | Dnum;
  4. Enable tree shaking in dnum

    main

    To reduce your bundle size by only including the functions you actually use, use named imports instead of importing the entire module. This allows modern bundlers to perform tree shaking effectively.

    import { format, from } from "dnum";
  5. Use the dnum public API

    main

    The dnum library provides a suite of functions for high-precision decimal arithmetic and formatting. The public API is organized into several functional groups:

    • Creation & Conversion: from, fromJSON, isDnum, toNumber, toString, toJSON, toParts.
    • Arithmetic Operations: add, subtract, multiply, divide, remainder.
    • Comparison & Logic: equal, compare, greaterThan, greaterThanOrEqual, lessThan, lessThanOrEqual.
    • Rounding & Math: round, ceil, floor, abs.
    • Formatting: format.
    • Decimal Management: setDecimals, equalizeDecimals.

    Many functions provide aliases for brevity (e.g., add is available as add, compare as cmp, equal as eq, greaterThan as gt, lessThan as lt, multiply as mul, subtract as sub, divide as div, and remainder as rem).

    import {
      from,
      add,
      equal,
      format
    } from 'dnum';
    
    const val = from(10.5, 2);
    const result = add(val, from(5, 2));
    console.log(equal(result, from(15.5, 2))); // true
    console.log(format(result));
  6. Use Numberish for flexible input types

    main

    The Numberish type is a union used across the API to allow users to pass values in various formats. You can provide a value as a bigint, number, string, or a Dnum tuple. This makes the library easy to integrate with existing numeric data.

    type Numberish = bigint | number | string | Dnum;
  7. Convert values to Dnum using from()

    main

    The from(valueToParse, decimals) function parses a string, number, bigint, or Dnum and converts it into a standard Dnum tuple. If decimals is set to true, it attempts to auto-detect decimals.

    // Parses a number expressed as a string or number
    let amount = dnum.from("17.30624", 18);
    // amount equals [17306240000000000000n, 18]
  8. Format Dnum values with format()

    main

    Use dn.format(value, options) to convert a Dnum into a human-readable string.

    • value: The Dnum tuple to format.
    • options: Can be a number representing the desired decimal places, or an options object.

    Supported options include { compact: true } for compact notation (e.g., '1.7B').

    import * as dn from "dnum";
    
    let b = dn.from("870983127.93887");
    
    dn.format(b, 2); // "870,983,127.94"
    dn.format(b, { compact: true }); // "1.7B"
  9. Perform math operations with multiply()

    main

    The dn.multiply(value1, value2, optionsOrDecimals) function multiplies two numbers. The inputs can be Dnum tuples or values that dn.from() can parse (like strings or numbers).

    import * as dn from "dnum";
    
    let a = dn.from(2, 18);
    let b = dn.from("870983127.93887");
    
    let c = dn.multiply(a, b); // returns [1741966255877740000000000000n, 18]
  10. Rounding and Math utilities

    main

    Standard math operations adapted for Dnum:

    • abs(value, decimals): Returns the absolute value. Alias: abs().
    • round(value, optionsOrDecimals): Rounds to the nearest integer (or specified decimal precision). options.rounding sets the method.
    • floor(value, decimals): Rounds down to the largest integer less than or equal to the number.
    • ceil(value, decimals): Rounds up to the smallest integer greater than or equal to the number.
    • setDecimals(value, decimals, options): Returns a new Dnum with a different decimal count. If reducing decimals, options.round determines the rounding method (defaults to "ROUND_HALF").
    let value = [-100000n, 2];
    dnum.abs(value); // [100000n, 2]
    
    let roundVal = [-123456n, 2]; // 1234.56
    dnum.round(roundVal); // [123500n, 2]
  11. Convert Dnum to primitive types

    main

    Convert a Dnum to standard JavaScript types. Note that toNumber and toString may result in precision loss for very large numbers.

    • toNumber(value, optionsOrDigits): Converts to a number. options.digits sets precision. options.decimalsRounding sets rounding method.
    • toString(value, optionsOrDigits): Converts to a string without formatting. options.digits sets precision. options.decimalsRounding sets rounding method.
    • toJSON(value): Converts to a JSON-compatible string (e.g., "[\"123\", 2]"). Use this for safe serialization since JSON.stringify does not support BigInt.
    • fromJSON(value): Parses a string produced by toJSON() back into a Dnum.
    let value = [123456789000000000000000n, 18];
    
    dnum.toNumber(value); // 123456.789
    dnum.toNumber(value, 1); // 123456.8
    
    dnum.toString(value, { digits: 1 }); // "123456.8"
    
    let json = dnum.toJSON([123456789000000000000n, 18]);
    // json == "[\"123456789000000000000\", 18]"
    
    let dnum = dnum.fromJSON(json);