Skip to content
Effect 4.0 is here. One ecosystem. Zero dependencies.

BigDecimal

This module provides utility functions and type class instances for working with the BigDecimal type in TypeScript. It includes functions for basic arithmetic operations, as well as type class instances for Equivalence and Order.

A BigDecimal allows storing any real number to arbitrary precision; which avoids common floating point errors (such as 0.1 + 0.2 โ‰  0.3) at the cost of complexity.

Internally, BigDecimal uses a BigInt object, paired with a 64-bit integer which determines the position of the decimal point. Therefore, the precision is not actually arbitrary, but limited to 263 decimal places.

It is not recommended to convert a floating point number to a decimal directly, as the floating point representation may be unexpected.

See

  • :BigInt for more similar operations on bigint types
  • :Number for more similar operations on number types
47 exports Since v2.0.0 Source

Constructors

Creates a BigDecimal from a bigint value.

Signature

declare function fromBigInt(n: bigint): BigDecimal

Creates a BigDecimal from a number value.

It is not recommended to convert a floating point number to a decimal directly, as the floating point representation may be unexpected.

Throws a RangeError if the number is not finite (NaN, +Infinity or -Infinity).

Signature

declare const fromNumber: (n: number) => BigDecimal

Parses a numerical string into a BigDecimal.

Signature

declare function fromString(s: string): Option<BigDecimal>

Example

import * as assert from "node:assert"
import { BigDecimal, Option } from "effect"
assert.deepStrictEqual(BigDecimal.fromString("123"), Option.some(BigDecimal.make(123n, 0)))
assert.deepStrictEqual(BigDecimal.fromString("123.456"), Option.some(BigDecimal.make(123456n, 3)))
assert.deepStrictEqual(BigDecimal.fromString("123.abc"), Option.none())
Since v2.0.0

Creates a BigDecimal from a bigint value and a scale.

Signature

declare function make(value: bigint, scale: number): BigDecimal

Creates a BigDecimal from a number value.

It is not recommended to convert a floating point number to a decimal directly, as the floating point representation may be unexpected.

Returns None if the number is not finite (NaN, +Infinity or -Infinity).

Signature

declare function safeFromNumber(n: number): Option<BigDecimal>

Example

import * as assert from "node:assert"
import { BigDecimal, Option } from "effect"
assert.deepStrictEqual(BigDecimal.safeFromNumber(123), Option.some(BigDecimal.make(123n, 0)))
assert.deepStrictEqual(BigDecimal.safeFromNumber(123.456), Option.some(BigDecimal.make(123456n, 3)))
assert.deepStrictEqual(BigDecimal.safeFromNumber(Infinity), Option.none())

Creates a BigDecimal from a number value.

It is not recommended to convert a floating point number to a decimal directly, as the floating point representation may be unexpected.

Throws a RangeError if the number is not finite (NaN, +Infinity or -Infinity).

Signature

declare function unsafeFromNumber(n: number): BigDecimal

Example

import * as assert from "node:assert"
import { unsafeFromNumber, make } from "effect/BigDecimal"
assert.deepStrictEqual(unsafeFromNumber(123), make(123n, 0))
assert.deepStrictEqual(unsafeFromNumber(123.456), make(123456n, 3))

Parses a numerical string into a BigDecimal.

Signature

declare function unsafeFromString(s: string): BigDecimal

Example

import * as assert from "node:assert"
import { unsafeFromString, make } from "effect/BigDecimal"
assert.deepStrictEqual(unsafeFromString("123"), make(123n, 0))
assert.deepStrictEqual(unsafeFromString("123.456"), make(123456n, 3))
assert.throws(() => unsafeFromString("123.abc"))

Conversions

Since v2.0.0

Formats a given BigDecimal as a string.

If the scale of the BigDecimal is greater than or equal to 16, the BigDecimal will be formatted in scientific notation.

Signature

declare function format(n: BigDecimal): string

Example

import * as assert from "node:assert"
import { format, unsafeFromString } from "effect/BigDecimal"
assert.deepStrictEqual(format(unsafeFromString("-5")), "-5")
assert.deepStrictEqual(format(unsafeFromString("123.456")), "123.456")
assert.deepStrictEqual(format(unsafeFromString("-0.00000123")), "-0.00000123")

Formats a given BigDecimal as a string in scientific notation.

Signature

declare function toExponential(n: BigDecimal): string

Example

import * as assert from "node:assert"
import { toExponential, make } from "effect/BigDecimal"
assert.deepStrictEqual(toExponential(make(123456n, -5)), "1.23456e+10")

Converts a BigDecimal to a number.

This function will produce incorrect results if the BigDecimal exceeds the 64-bit range of a number.

Signature

declare function unsafeToNumber(n: BigDecimal): number

Example

import * as assert from "node:assert"
import { unsafeToNumber, unsafeFromString } from "effect/BigDecimal"
assert.deepStrictEqual(unsafeToNumber(unsafeFromString("123.456")), 123.456)

Guards

Checks if a given value is a BigDecimal.

Signature

declare function isBigDecimal(u: unknown): u is BigDecimal

Instances

Signature

declare const Equivalence: equivalence.Equivalence<BigDecimal>
Since v2.0.0

Signature

declare const Order: order.Order<BigDecimal>

Math

Since v2.0.0

Determines the absolute value of a given BigDecimal.

Signature

declare function abs(n: BigDecimal): BigDecimal

Example

import * as assert from "node:assert"
import { abs, unsafeFromString } from "effect/BigDecimal"
assert.deepStrictEqual(abs(unsafeFromString("-5")), unsafeFromString("5"))
assert.deepStrictEqual(abs(unsafeFromString("0")), unsafeFromString("0"))
assert.deepStrictEqual(abs(unsafeFromString("5")), unsafeFromString("5"))
Since v3.16.0

Calculate the ceiling of a BigDecimal at the given scale.

Signature

declare const ceil: {
(scale: number): (self: BigDecimal) => BigDecimal;
(self: BigDecimal, scale?: number): BigDecimal;
}

Example

import * as assert from "node:assert"
import { ceil, unsafeFromString } from "effect/BigDecimal"
assert.deepStrictEqual(ceil(unsafeFromString("145"), -1), unsafeFromString("150"))
assert.deepStrictEqual(ceil(unsafeFromString("-14.5")), unsafeFromString("-14"))
Since v2.0.0

Restricts the given BigDecimal to be within the range specified by the minimum and maximum values.

  • If the BigDecimal is less than the minimum value, the function returns the minimum value.
  • If the BigDecimal is greater than the maximum value, the function returns the maximum value.
  • Otherwise, it returns the original BigDecimal.

Signature

declare const clamp: {
(options: {
maximum: BigDecimal;
minimum: BigDecimal;
}): (self: BigDecimal) => BigDecimal;
(self: BigDecimal, options: {
maximum: BigDecimal;
minimum: BigDecimal;
}): BigDecimal;
}

Example

import * as assert from "node:assert"
import { BigDecimal } from "effect"
const clamp = BigDecimal.clamp({
minimum: BigDecimal.unsafeFromString("1"),
maximum: BigDecimal.unsafeFromString("5") }
)
assert.deepStrictEqual(clamp(BigDecimal.unsafeFromString("3")), BigDecimal.unsafeFromString("3"))
assert.deepStrictEqual(clamp(BigDecimal.unsafeFromString("0")), BigDecimal.unsafeFromString("1"))
assert.deepStrictEqual(clamp(BigDecimal.unsafeFromString("6")), BigDecimal.unsafeFromString("5"))
Since v2.0.0

Provides a division operation on BigDecimals.

If the dividend is not a multiple of the divisor the result will be a BigDecimal value which represents the integer division rounded down to the nearest integer.

If the divisor is 0, the result will be None.

Signature

declare const divide: {
(that: BigDecimal): (self: BigDecimal) => Option<BigDecimal>;
(self: BigDecimal, that: BigDecimal): Option<BigDecimal>;
}

Example

import * as assert from "node:assert"
import { BigDecimal, Option } from "effect"
assert.deepStrictEqual(BigDecimal.divide(BigDecimal.unsafeFromString("6"), BigDecimal.unsafeFromString("3")), Option.some(BigDecimal.unsafeFromString("2")))
assert.deepStrictEqual(BigDecimal.divide(BigDecimal.unsafeFromString("6"), BigDecimal.unsafeFromString("4")), Option.some(BigDecimal.unsafeFromString("1.5")))
assert.deepStrictEqual(BigDecimal.divide(BigDecimal.unsafeFromString("6"), BigDecimal.unsafeFromString("0")), Option.none())
Since v3.16.0

Calculate the floor of a BigDecimal at the given scale.

Signature

declare const floor: {
(scale: number): (self: BigDecimal) => BigDecimal;
(self: BigDecimal, scale?: number): BigDecimal;
}

Example

import * as assert from "node:assert"
import { floor, unsafeFromString } from "effect/BigDecimal"
assert.deepStrictEqual(floor(unsafeFromString("145"), -1), unsafeFromString("140"))
assert.deepStrictEqual(floor(unsafeFromString("-14.5")), unsafeFromString("-15"))
Since v2.0.0

Returns the maximum between two BigDecimals.

Signature

declare const max: {
(that: BigDecimal): (self: BigDecimal) => BigDecimal;
(self: BigDecimal, that: BigDecimal): BigDecimal;
}

Example

import * as assert from "node:assert"
import { max, unsafeFromString } from "effect/BigDecimal"
assert.deepStrictEqual(max(unsafeFromString("2"), unsafeFromString("3")), unsafeFromString("3"))
Since v2.0.0

Returns the minimum between two BigDecimals.

Signature

declare const min: {
(that: BigDecimal): (self: BigDecimal) => BigDecimal;
(self: BigDecimal, that: BigDecimal): BigDecimal;
}

Example

import * as assert from "node:assert"
import { min, unsafeFromString } from "effect/BigDecimal"
assert.deepStrictEqual(min(unsafeFromString("2"), unsafeFromString("3")), unsafeFromString("2"))
Since v2.0.0

Provides a multiplication operation on BigDecimals.

Signature

declare const multiply: {
(that: BigDecimal): (self: BigDecimal) => BigDecimal;
(self: BigDecimal, that: BigDecimal): BigDecimal;
}

Example

import * as assert from "node:assert"
import { multiply, unsafeFromString } from "effect/BigDecimal"
assert.deepStrictEqual(multiply(unsafeFromString("2"), unsafeFromString("3")), unsafeFromString("6"))
Since v2.0.0

Provides a negate operation on BigDecimals.

Signature

declare function negate(n: BigDecimal): BigDecimal

Example

import * as assert from "node:assert"
import { negate, unsafeFromString } from "effect/BigDecimal"
assert.deepStrictEqual(negate(unsafeFromString("3")), unsafeFromString("-3"))
assert.deepStrictEqual(negate(unsafeFromString("-6")), unsafeFromString("6"))

Returns the remainder left over when one operand is divided by a second operand.

If the divisor is 0, the result will be None.

Signature

declare const remainder: {
(divisor: BigDecimal): (self: BigDecimal) => Option<BigDecimal>;
(self: BigDecimal, divisor: BigDecimal): Option<BigDecimal>;
}

Example

import * as assert from "node:assert"
import { BigDecimal, Option } from "effect"
assert.deepStrictEqual(BigDecimal.remainder(BigDecimal.unsafeFromString("2"), BigDecimal.unsafeFromString("2")), Option.some(BigDecimal.unsafeFromString("0")))
assert.deepStrictEqual(BigDecimal.remainder(BigDecimal.unsafeFromString("3"), BigDecimal.unsafeFromString("2")), Option.some(BigDecimal.unsafeFromString("1")))
assert.deepStrictEqual(BigDecimal.remainder(BigDecimal.unsafeFromString("-4"), BigDecimal.unsafeFromString("2")), Option.some(BigDecimal.unsafeFromString("0")))
Since v3.16.0

Rounds a BigDecimal at the given scale with the specified rounding mode.

Signature

declare const round: {
(options: {
mode?: RoundingMode;
scale?: number;
}): (self: BigDecimal) => BigDecimal;
(n: BigDecimal, options?: {
mode?: RoundingMode;
scale?: number;
}): BigDecimal;
}

Example

import * as assert from "node:assert"
import { round, unsafeFromString } from "effect/BigDecimal"
assert.deepStrictEqual(round(unsafeFromString("145"), { mode: "from-zero", scale: -1 }), unsafeFromString("150"))
assert.deepStrictEqual(round(unsafeFromString("-14.5")), unsafeFromString("-15"))
Since v3.16.0

Rounding modes for BigDecimal.

ceil: round towards positive infinity floor: round towards negative infinity to-zero: round towards zero from-zero: round away from zero half-ceil: round to the nearest neighbor; if equidistant round towards positive infinity half-floor: round to the nearest neighbor; if equidistant round towards negative infinity half-to-zero: round to the nearest neighbor; if equidistant round towards zero half-from-zero: round to the nearest neighbor; if equidistant round away from zero half-even: round to the nearest neighbor; if equidistant round to the neighbor with an even digit half-odd: round to the nearest neighbor; if equidistant round to the neighbor with an odd digit

Signature

type RoundingMode = "ceil" | "floor" | "to-zero" | "from-zero" | "half-ceil" | "half-floor" | "half-to-zero" | "half-from-zero" | "half-even" | "half-odd"
Since v2.0.0

Determines the sign of a given BigDecimal.

Signature

declare function sign(n: BigDecimal): Ordering

Example

import * as assert from "node:assert"
import { sign, unsafeFromString } from "effect/BigDecimal"
assert.deepStrictEqual(sign(unsafeFromString("-5")), -1)
assert.deepStrictEqual(sign(unsafeFromString("0")), 0)
assert.deepStrictEqual(sign(unsafeFromString("5")), 1)
Since v2.0.0

Provides a subtraction operation on BigDecimals.

Signature

declare const subtract: {
(that: BigDecimal): (self: BigDecimal) => BigDecimal;
(self: BigDecimal, that: BigDecimal): BigDecimal;
}

Example

import * as assert from "node:assert"
import { subtract, unsafeFromString } from "effect/BigDecimal"
assert.deepStrictEqual(subtract(unsafeFromString("2"), unsafeFromString("3")), unsafeFromString("-1"))
Since v2.0.0

Provides an addition operation on BigDecimals.

Signature

declare const sum: {
(that: BigDecimal): (self: BigDecimal) => BigDecimal;
(self: BigDecimal, that: BigDecimal): BigDecimal;
}

Example

import * as assert from "node:assert"
import { sum, unsafeFromString } from "effect/BigDecimal"
assert.deepStrictEqual(sum(unsafeFromString("2"), unsafeFromString("3")), unsafeFromString("5"))
Since v3.16.0

Takes an Iterable of BigDecimals and returns their sum as a single BigDecimal

Signature

declare function sumAll(collection: Iterable<BigDecimal>): BigDecimal

Example

import * as assert from "node:assert"
import { unsafeFromString, sumAll } from "effect/BigDecimal"
assert.deepStrictEqual(sumAll([unsafeFromString("2"), unsafeFromString("3"), unsafeFromString("4")]), unsafeFromString("9"))
Since v3.16.0

Truncate a BigDecimal at the given scale. This is the same operation as rounding away from zero.

Signature

declare const truncate: {
(scale: number): (self: BigDecimal) => BigDecimal;
(self: BigDecimal, scale?: number): BigDecimal;
}

Example

import * as assert from "node:assert"
import { truncate, unsafeFromString } from "effect/BigDecimal"
assert.deepStrictEqual(truncate(unsafeFromString("145"), -1), unsafeFromString("140"))
assert.deepStrictEqual(truncate(unsafeFromString("-14.5")), unsafeFromString("-14"))

Provides an unsafe division operation on BigDecimals.

If the dividend is not a multiple of the divisor the result will be a BigDecimal value which represents the integer division rounded down to the nearest integer.

Throws a RangeError if the divisor is 0.

Signature

declare const unsafeDivide: {
(that: BigDecimal): (self: BigDecimal) => BigDecimal;
(self: BigDecimal, that: BigDecimal): BigDecimal;
}

Example

import * as assert from "node:assert"
import { unsafeDivide, unsafeFromString } from "effect/BigDecimal"
assert.deepStrictEqual(unsafeDivide(unsafeFromString("6"), unsafeFromString("3")), unsafeFromString("2"))
assert.deepStrictEqual(unsafeDivide(unsafeFromString("6"), unsafeFromString("4")), unsafeFromString("1.5"))

Returns the remainder left over when one operand is divided by a second operand.

Throws a RangeError if the divisor is 0.

Signature

declare const unsafeRemainder: {
(divisor: BigDecimal): (self: BigDecimal) => BigDecimal;
(self: BigDecimal, divisor: BigDecimal): BigDecimal;
}

Example

import * as assert from "node:assert"
import { unsafeRemainder, unsafeFromString } from "effect/BigDecimal"
assert.deepStrictEqual(unsafeRemainder(unsafeFromString("2"), unsafeFromString("2")), unsafeFromString("0"))
assert.deepStrictEqual(unsafeRemainder(unsafeFromString("3"), unsafeFromString("2")), unsafeFromString("1"))
assert.deepStrictEqual(unsafeRemainder(unsafeFromString("-4"), unsafeFromString("2")), unsafeFromString("0"))

Models

BigDecimal

interface
Since v2.0.0

Signature

interface BigDecimal extends Equal, Pipeable, Inspectable {
readonly [TypeId]: typeof TypeId;
readonly scale: number;
readonly value: bigint;
}

Predicates

Since v2.0.0

Checks if a BigDecimal is between a minimum and maximum value (inclusive).

Signature

declare const between: {
(options: {
maximum: BigDecimal;
minimum: BigDecimal;
}): (self: BigDecimal) => boolean;
(self: BigDecimal, options: {
maximum: BigDecimal;
minimum: BigDecimal;
}): boolean;
}

Example

import * as assert from "node:assert"
import { BigDecimal } from "effect"
const between = BigDecimal.between({
minimum: BigDecimal.unsafeFromString("1"),
maximum: BigDecimal.unsafeFromString("5") }
)
assert.deepStrictEqual(between(BigDecimal.unsafeFromString("3")), true)
assert.deepStrictEqual(between(BigDecimal.unsafeFromString("0")), false)
assert.deepStrictEqual(between(BigDecimal.unsafeFromString("6")), false)
Since v2.0.0

Checks if two BigDecimals are equal.

Signature

declare const equals: {
(that: BigDecimal): (self: BigDecimal) => boolean;
(self: BigDecimal, that: BigDecimal): boolean;
}

Returns true if the first argument is greater than the second, otherwise false.

Signature

declare const greaterThan: {
(that: BigDecimal): (self: BigDecimal) => boolean;
(self: BigDecimal, that: BigDecimal): boolean;
}

Example

import * as assert from "node:assert"
import { greaterThan, unsafeFromString } from "effect/BigDecimal"
assert.deepStrictEqual(greaterThan(unsafeFromString("2"), unsafeFromString("3")), false)
assert.deepStrictEqual(greaterThan(unsafeFromString("3"), unsafeFromString("3")), false)
assert.deepStrictEqual(greaterThan(unsafeFromString("4"), unsafeFromString("3")), true)

Checks if a given BigDecimal is greater than or equal to the provided one.

Signature

declare const greaterThanOrEqualTo: {
(that: BigDecimal): (self: BigDecimal) => boolean;
(self: BigDecimal, that: BigDecimal): boolean;
}

Example

import * as assert from "node:assert"
import { greaterThanOrEqualTo, unsafeFromString } from "effect/BigDecimal"
assert.deepStrictEqual(greaterThanOrEqualTo(unsafeFromString("2"), unsafeFromString("3")), false)
assert.deepStrictEqual(greaterThanOrEqualTo(unsafeFromString("3"), unsafeFromString("3")), true)
assert.deepStrictEqual(greaterThanOrEqualTo(unsafeFromString("4"), unsafeFromString("3")), true)

Checks if a given BigDecimal is an integer.

Signature

declare function isInteger(n: BigDecimal): boolean

Example

import * as assert from "node:assert"
import { isInteger, unsafeFromString } from "effect/BigDecimal"
assert.deepStrictEqual(isInteger(unsafeFromString("0")), true)
assert.deepStrictEqual(isInteger(unsafeFromString("1")), true)
assert.deepStrictEqual(isInteger(unsafeFromString("1.1")), false)

Checks if a given BigDecimal is negative.

Signature

declare function isNegative(n: BigDecimal): boolean

Example

import * as assert from "node:assert"
import { isNegative, unsafeFromString } from "effect/BigDecimal"
assert.deepStrictEqual(isNegative(unsafeFromString("-1")), true)
assert.deepStrictEqual(isNegative(unsafeFromString("0")), false)
assert.deepStrictEqual(isNegative(unsafeFromString("1")), false)

Checks if a given BigDecimal is positive.

Signature

declare function isPositive(n: BigDecimal): boolean

Example

import * as assert from "node:assert"
import { isPositive, unsafeFromString } from "effect/BigDecimal"
assert.deepStrictEqual(isPositive(unsafeFromString("-1")), false)
assert.deepStrictEqual(isPositive(unsafeFromString("0")), false)
assert.deepStrictEqual(isPositive(unsafeFromString("1")), true)
Since v2.0.0

Checks if a given BigDecimal is 0.

Signature

declare function isZero(n: BigDecimal): boolean

Example

import * as assert from "node:assert"
import { isZero, unsafeFromString } from "effect/BigDecimal"
assert.deepStrictEqual(isZero(unsafeFromString("0")), true)
assert.deepStrictEqual(isZero(unsafeFromString("1")), false)
Since v2.0.0

Returns true if the first argument is less than the second, otherwise false.

Signature

declare const lessThan: {
(that: BigDecimal): (self: BigDecimal) => boolean;
(self: BigDecimal, that: BigDecimal): boolean;
}

Example

import * as assert from "node:assert"
import { lessThan, unsafeFromString } from "effect/BigDecimal"
assert.deepStrictEqual(lessThan(unsafeFromString("2"), unsafeFromString("3")), true)
assert.deepStrictEqual(lessThan(unsafeFromString("3"), unsafeFromString("3")), false)
assert.deepStrictEqual(lessThan(unsafeFromString("4"), unsafeFromString("3")), false)

Checks if a given BigDecimal is less than or equal to the provided one.

Signature

declare const lessThanOrEqualTo: {
(that: BigDecimal): (self: BigDecimal) => boolean;
(self: BigDecimal, that: BigDecimal): boolean;
}

Example

import * as assert from "node:assert"
import { lessThanOrEqualTo, unsafeFromString } from "effect/BigDecimal"
assert.deepStrictEqual(lessThanOrEqualTo(unsafeFromString("2"), unsafeFromString("3")), true)
assert.deepStrictEqual(lessThanOrEqualTo(unsafeFromString("3"), unsafeFromString("3")), true)
assert.deepStrictEqual(lessThanOrEqualTo(unsafeFromString("4"), unsafeFromString("3")), false)

Scaling

Normalizes a given BigDecimal by removing trailing zeros.

Signature

declare function normalize(self: BigDecimal): BigDecimal

Example

import * as assert from "node:assert"
import { normalize, make, unsafeFromString } from "effect/BigDecimal"
assert.deepStrictEqual(normalize(unsafeFromString("123.00000")), normalize(make(123n, 0)))
assert.deepStrictEqual(normalize(unsafeFromString("12300000")), normalize(make(123n, -5)))
Since v2.0.0

Scales a given BigDecimal to the specified scale.

If the given scale is smaller than the current scale, the value will be rounded down to the nearest integer.

Signature

declare const scale: {
(scale: number): (self: BigDecimal) => BigDecimal;
(self: BigDecimal, scale: number): BigDecimal;
}

Symbol

Since v2.0.0

Signature

type TypeId = typeof TypeId

Symbols

Since v2.0.0

Signature

declare const TypeId: unique symbol