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

Number.ts 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 intModulo when you need a positive modulo (the JavaScript % operator is sign-preserving).

Common tasks

  • Convert from bigint: unsafeFromBigInt, fromBigInt
  • Convert from BigDecimal: unsafeFromBigDecimal, fromBigDecimal
  • Convert from string: unsafeFromString
  • Arithmetic: opposite, intModulo, quotientAndRemainder, shift
  • Predicates: equals, isMultipleOf
  • Sign: sign2
  • Constants: MAX_SAFE_INTEGER, MIN_SAFE_INTEGER

Quickstart

Example (Safe conversion and positive modulo)

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

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

Exports Grouped by Category


Constructors

fromBigDecimal

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.

See

  • unsafeFromBigDecimal — unchecked variant

Signature

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

Source

fromBigInt

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.fromBigInt(42n)) // Some(42)
console.log(MNumber.fromBigInt(2n ** 100n)) // None

See

  • unsafeFromBigInt — unchecked variant

Signature

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

Source

fromFormatAndString

Returns a function that tries to convert a whole string into a number respecting format. Unlike fromFormatAndStringStart, the whole of the input string must represent a number.

  • Use a precomputed parser when the same format will be applied many times.

Example (Parse a number from a whole string)

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

const parse = MNumber.fromFormatAndString(MNumberBase10Format.frenchStyleNumber)
console.log(parse("-45,50")) // Some(-45.5)
console.log(parse("-45,50Dummy")) // None

Signature

declare const fromFormatAndString: (
  format: MNumberBase10Format.Type
) => MTypes.OneArgFunction<string, Option.Option<number>>

Source

fromFormatAndStringOrThrow

Same as fromFormatAndString but throws in case of failure

Signature

declare const fromFormatAndStringOrThrow: (format: MNumberBase10Format.Type) => MTypes.OneArgFunction<string, number>

Source

fromFormatAndStringStart

Returns a function that tries to extract, from the start of a string, a number respecting format. If successful, returns a some of a [value, match] pair where match is the part of the string that could be analyzed as representing a number. Otherwise, returns a none. Unlike BigDecimal, number distinguishes -0 from 0.

  • Use a precomputed extractor when the same format will be applied many times.

Example (Extract a number from the start of a string)

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

const extract = MNumber.fromFormatAndStringStart(MNumberBase10Format.frenchStyleNumber)
console.log(extract("-45,50Dummy")) // Some([-45.5, '-45,50'])

Signature

declare const fromFormatAndStringStart: (
  format: MNumberBase10Format.Type
) => MTypes.OneArgFunction<string, Option.Option<[value: number, match: string]>>

Source

fromFormatAndStringStartOrThrow

Same as fromFormatAndStringStart but throws in case of failure

Signature

declare const fromFormatAndStringStartOrThrow: (
  format: MNumberBase10Format.Type
) => MTypes.OneArgFunction<string, [value: number, match: string]>

Source

unsafeFromBigDecimal

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

See

  • fromBigDecimal — safe variant

Signature

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

Source

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

See

  • fromBigInt — safe variant

Signature

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

Source

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

declare const unsafeFromString: MTypes.NumberFromString

Source

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

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

Source

Models

Type (type alias)

Type on which this module’s functions operate.

Signature

type Type = number

Source

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

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

Source

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

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

Source

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

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

Source

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

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

Source

round

Returns a function that rounds self to precision decimal digits according to option.

  • Use a precomputed rounder when the same precision/option pair will be applied many times.

Example (Round to three decimal digits, half to even)

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

const round = MNumber.round(3, MNumberBase10Format.RoundingOption.HalfEven)
console.log(pipe(12.4565, round)) // 12.456

Signature

declare const round: (precision: number, option: MNumberBase10Format.RoundingOption) => MTypes.OneArgFunction<Type>

Source

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

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

Source

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

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

Source