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