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
Typeis justnumber.- Conversions come in
unsafe*(lossy: too-large or non-finite values become±InfinityorNaN) and*Option(validating, returningOption) 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'produceInfinity;'-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
selfanda.
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 ofself). - 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 returns0/-0for 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.
precisionmust be a non-negative finite integer; defaults to0.- 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