Skip to main content Link Search Menu Expand Document (external link)

Number overview

Extension to the effect/Number module providing safe conversions from bigint and BigDecimal, positive integer modulo, decimal shifting and truncation, and a few numeric predicates.

Mental model

  • Type is just number.
  • Conversions come in unsafe* (lossy: too-large or non-finite values become ±Infinity or NaN) and *Option (validating, returning Option) flavors.
  • Use {@link intModulo} when you need a positive modulo (the JavaScript % operator is sign-preserving).

Common tasks

  • Convert from bigint: {@link unsafeFromBigInt}, {@link fromBigIntOption}
  • Convert from BigDecimal: {@link unsafeFromBigDecimal}, {@link fromBigDecimalOption}
  • Convert from string: {@link unsafeFromString}
  • Arithmetic: {@link opposite}, {@link intModulo}, {@link quotientAndRemainder}, {@link shift}, {@link trunc}
  • Predicates: {@link equals}, {@link isMultipleOf}
  • Sign: {@link sign2}
  • Constants: {@link MAX_SAFE_INTEGER}, {@link MIN_SAFE_INTEGER}

Quickstart

Example (Safe conversion and positive modulo)

import * as MNumber from "@parischap/effect-lib/MNumber"

console.log(MNumber.fromBigIntOption(123n)) // Some(123)
console.log(MNumber.intModulo(3)(-7)) // 2 (vs. -7 % 3 === -1)

Table of contents


Constants

{ MAX_SAFE_INTEGER, MIN_SAFE_INTEGER }

Number.MAX_SAFE_INTEGER (2^53 − 1) and Number.MIN_SAFE_INTEGER (−(2^53 − 1)).

Signature

export declare const { MAX_SAFE_INTEGER, MIN_SAFE_INTEGER }: any

Constructors

fromBigDecimalOption

Builds a number from a BigDecimal, returning Option.some when the input lies in [Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER] and Option.none otherwise.

Signature

export declare const fromBigDecimalOption: MTypes.OneArgFunction<BigDecimal.BigDecimal, Option.Option<number>>

fromBigIntOption

Builds a number from a bigint, returning Option.some when the input lies in [Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER] and Option.none otherwise.

Example (Safe conversion)

import * as MNumber from "@parischap/effect-lib/MNumber"

console.log(MNumber.fromBigIntOption(42n)) // Some(42)
console.log(MNumber.fromBigIntOption(2n ** 100n)) // None

Signature

export declare const fromBigIntOption: MTypes.OneArgFunction<bigint, Option.Option<number>>

unsafeFromBigDecimal

Builds a number from a BigDecimal without range checks. Values outside the safe-integer range are coerced to ±Infinity.

Signature

export declare const unsafeFromBigDecimal: MTypes.OneArgFunction<BigDecimal.BigDecimal, number>

unsafeFromBigInt

Builds a number from a bigint without range checks. Values outside the safe-integer range are coerced to ±Infinity.

  • Use only when the input is statically known to fit in a JavaScript number.

Example (Lossy conversion)

import * as MNumber from "@parischap/effect-lib/MNumber"

console.log(MNumber.unsafeFromBigInt(42n)) // 42
console.log(MNumber.unsafeFromBigInt(2n ** 100n)) // Infinity

Signature

export declare const unsafeFromBigInt: MTypes.OneArgFunction<bigint, number>

unsafeFromString

Builds a number from a string. Returns NaN when the string is not a valid numeric literal.

  • 'Infinity' / '+Infinity' produce Infinity; '-Infinity' produces -Infinity.

Example (String to number)

import * as MNumber from "@parischap/effect-lib/MNumber"

console.log(MNumber.unsafeFromString("42")) // 42
console.log(MNumber.unsafeFromString("abc")) // NaN

Signature

export declare const unsafeFromString: MTypes.NumberFromString

Destructors

quotientAndRemainder

Returns [quotient, remainder] for the Euclidean division of self by divisor. The remainder carries the sign of divisor.

  • Both inputs must be finite integers; otherwise the result is meaningless.

Example (Quotient and remainder)

import { pipe } from "effect"
import * as MNumber from "@parischap/effect-lib/MNumber"

console.log(pipe(7, MNumber.quotientAndRemainder(3))) // [2, 1]
console.log(pipe(-7, MNumber.quotientAndRemainder(3))) // [-3, 2]

Signature

export declare const quotientAndRemainder: (divisor: number) => (self: Type) => [quotient: number, remainder: number]

Models

Type (type alias)

Type on which this module’s functions operate.

Signature

export type Type = number

Predicates

equals

Returns true when self and n differ by less than Number.EPSILON.

  • Use to compare floating-point numbers where exact === is unreliable.
  • This is an absolute, not relative, tolerance — it is not appropriate for very large magnitudes.

Example (Floating-point equality)

import { pipe } from "effect"
import * as MNumber from "@parischap/effect-lib/MNumber"

console.log(pipe(0.1 + 0.2, MNumber.equals(0.3))) // true

Signature

export declare const equals: (n: number) => Predicate.Predicate<Type>

isMultipleOf

Returns true when self is a multiple of a.

  • Works for any signs of self and a.

Example (Multiplicity check)

import { pipe } from "effect"
import * as MNumber from "@parischap/effect-lib/MNumber"

console.log(pipe(10, MNumber.isMultipleOf(2))) // true
console.log(pipe(-9, MNumber.isMultipleOf(3))) // true

Signature

export declare const isMultipleOf: (a: number) => Predicate.Predicate<Type>

Utils

intModulo

Returns the non-negative remainder of the integer division of self by divisor.

  • Use when a positive remainder is needed (the built-in % preserves the sign of self).
  • Both inputs must be finite integers; otherwise the result is meaningless.

Example (Positive integer modulo)

import { pipe } from "effect"
import * as MNumber from "@parischap/effect-lib/MNumber"

console.log(pipe(-7, MNumber.intModulo(3))) // 2
console.log(pipe(7, MNumber.intModulo(3))) // 1

Signature

export declare const intModulo: (divisor: number) => MTypes.OneArgFunction<Type>

opposite

Returns the additive inverse of self (i.e. -self).

Example (Negation)

import * as MNumber from "@parischap/effect-lib/MNumber"

console.log(MNumber.opposite(3)) // -3
console.log(MNumber.opposite(-3)) // 3

Signature

export declare const opposite: (self: Type) => number

shift

Multiplies self by 10^n (i.e. shifts the decimal point by n positions).

  • Use as the building block of decimal-aware truncation/rounding.

Example (Decimal shift)

import { pipe } from "effect"
import * as MNumber from "@parischap/effect-lib/MNumber"

console.log(pipe(1.5, MNumber.shift(2))) // 150
console.log(pipe(150, MNumber.shift(-2))) // 1.5

Signature

export declare const shift: (n: number) => (self: Type) => number

sign2

Returns the sign of n as either 1 or -1. Treats +0 (and the unsigned literal 0) as positive and -0 as negative.

  • Differs from Math.sign, which returns 0/-0 for those inputs.

Example (Sign with ±0 distinction)

import * as MNumber from "@parischap/effect-lib/MNumber"

console.log(MNumber.sign2(3)) // 1
console.log(MNumber.sign2(-3)) // -1
console.log(MNumber.sign2(0)) // 1
console.log(MNumber.sign2(-0)) // -1

Signature

export declare const sign2: (n: number) => 1 | -1

trunc

Truncates self to precision decimal digits.

  • precision must be a non-negative finite integer; defaults to 0.
  • Rounds towards zero.

Example (Truncation)

import { pipe } from "effect"
import * as MNumber from "@parischap/effect-lib/MNumber"

console.log(pipe(3.14159, MNumber.trunc(2))) // 3.14
console.log(pipe(3.7, MNumber.trunc())) // 3

Signature

export declare const trunc: (precision?: number) => (self: Type) => number