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
biginttypes - :Number for more similar operations on
numbertypes
Constructors
fromBigInt
Creates a BigDecimal from a bigint value.
Signature
declare function fromBigInt(n: bigint): BigDecimalfromNumber
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) => BigDecimalfromString
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())Creates a BigDecimal from a bigint value and a scale.
Signature
declare function make(value: bigint, scale: number): BigDecimalsafeFromNumber
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())unsafeFromNumber
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): BigDecimalExample
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))unsafeFromString
Parses a numerical string into a BigDecimal.
Signature
declare function unsafeFromString(s: string): BigDecimalExample
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
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): stringExample
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")toExponential
Formats a given BigDecimal as a string in scientific notation.
Signature
declare function toExponential(n: BigDecimal): stringExample
import * as assert from "node:assert"import { toExponential, make } from "effect/BigDecimal"
assert.deepStrictEqual(toExponential(make(123456n, -5)), "1.23456e+10")unsafeToNumber
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): numberExample
import * as assert from "node:assert"import { unsafeToNumber, unsafeFromString } from "effect/BigDecimal"
assert.deepStrictEqual(unsafeToNumber(unsafeFromString("123.456")), 123.456)Guards
isBigDecimal
Checks if a given value is a BigDecimal.
Signature
declare function isBigDecimal(u: unknown): u is BigDecimalInstances
Equivalence
Signature
declare const Equivalence: equivalence.Equivalence<BigDecimal>Signature
declare const Order: order.Order<BigDecimal>Math
Determines the absolute value of a given BigDecimal.
Signature
declare function abs(n: BigDecimal): BigDecimalExample
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"))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"))Restricts the given BigDecimal to be within the range specified by the minimum and maximum values.
- If the
BigDecimalis less than theminimumvalue, the function returns theminimumvalue. - If the
BigDecimalis greater than themaximumvalue, the function returns themaximumvalue. - 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"))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())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"))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"))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"))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"))Provides a negate operation on BigDecimals.
Signature
declare function negate(n: BigDecimal): BigDecimalExample
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")))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"))RoundingMode type
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"Determines the sign of a given BigDecimal.
Signature
declare function sign(n: BigDecimal): OrderingExample
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)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"))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"))Takes an Iterable of BigDecimals and returns their sum as a single BigDecimal
Signature
declare function sumAll(collection: Iterable<BigDecimal>): BigDecimalExample
import * as assert from "node:assert"import { unsafeFromString, sumAll } from "effect/BigDecimal"
assert.deepStrictEqual(sumAll([unsafeFromString("2"), unsafeFromString("3"), unsafeFromString("4")]), unsafeFromString("9"))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"))unsafeDivide
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"))unsafeRemainder
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
Signature
interface BigDecimal extends Equal, Pipeable, Inspectable { readonly [TypeId]: typeof TypeId; readonly scale: number; readonly value: bigint;}Predicates
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)Checks if two BigDecimals are equal.
Signature
declare const equals: { (that: BigDecimal): (self: BigDecimal) => boolean; (self: BigDecimal, that: BigDecimal): boolean;}greaterThan
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)greaterThanOrEqualTo
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): booleanExample
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)isNegative
Checks if a given BigDecimal is negative.
Signature
declare function isNegative(n: BigDecimal): booleanExample
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)isPositive
Checks if a given BigDecimal is positive.
Signature
declare function isPositive(n: BigDecimal): booleanExample
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)Checks if a given BigDecimal is 0.
Signature
declare function isZero(n: BigDecimal): booleanExample
import * as assert from "node:assert"import { isZero, unsafeFromString } from "effect/BigDecimal"
assert.deepStrictEqual(isZero(unsafeFromString("0")), true)assert.deepStrictEqual(isZero(unsafeFromString("1")), false)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)lessThanOrEqualTo
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): BigDecimalExample
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)))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;}