or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.mdlocale-options.mdmathematical.mdnumber-formatting.mdutilities.mdvalidation.md
tile.json

number-formatting.mddocs/

Number Formatting

Comprehensive number formatting system implementing ECMA-402 NumberFormat abstract operations, including pattern processing, rounding, localized number display, and range formatting. These functions provide the core functionality for internationalized number formatting.

Capabilities

Core Formatting Functions

Main functions for formatting numbers and number ranges to strings and parts.

/**
 * Formats a number to a localized string representation
 * @param internalSlots - NumberFormat internal configuration
 * @param x - Number to format as Decimal
 * @returns Formatted number string
 */
function FormatNumeric(internalSlots: NumberFormatInternal, x: Decimal): string;

/**
 * Formats a number to an array of formatted parts
 * @param internalSlots - NumberFormat internal configuration
 * @param x - Number to format as Decimal
 * @returns Array of formatted number parts with type information
 */
function FormatNumericToParts(
  internalSlots: NumberFormatInternal,
  x: Decimal
): NumberFormatPart[];

/**
 * Formats a number to string with detailed formatting result
 * @param internalSlots - NumberFormat internal configuration
 * @param x - Number to format as Decimal
 * @returns Raw formatting result with roundedNumber and formattedString
 */
function FormatNumericToString(
  internalSlots: NumberFormatInternal,
  x: Decimal
): RawNumberFormatResult;

/**
 * Formats a range of numbers to a localized string
 * @param internalSlots - NumberFormat internal configuration
 * @param x - Start of range as Decimal
 * @param y - End of range as Decimal
 * @returns Formatted number range string
 */
function FormatNumericRange(
  internalSlots: NumberFormatInternal,
  x: Decimal,
  y: Decimal
): string;

/**
 * Formats a range of numbers to an array of parts
 * @param internalSlots - NumberFormat internal configuration
 * @param x - Start of range as Decimal
 * @param y - End of range as Decimal
 * @returns Array of formatted number range parts
 */
function FormatNumericRangeToParts(
  internalSlots: NumberFormatInternal,
  x: Decimal,
  y: Decimal
): NumberRangeToParts[];

Usage Examples:

import { 
  FormatNumeric, 
  FormatNumericToParts,
  FormatNumericRange,
  NumberFormatInternal
} from "@formatjs/ecma402-abstract";

// Example internal slots (normally created by InitializeNumberFormat)
const internalSlots: NumberFormatInternal = {
  locale: 'en-US',
  style: 'decimal',
  notation: 'standard',
  useGrouping: true,
  minimumFractionDigits: 0,
  maximumFractionDigits: 3,
  // ... other properties
};

const number = new Decimal('1234.567');

// Format to string
const formatted = FormatNumeric(internalSlots, number);
console.log(formatted); // '1,234.567'

// Format to parts
const parts = FormatNumericToParts(internalSlots, number);
console.log(parts);
// [
//   { type: 'integer', value: '1' },
//   { type: 'group', value: ',' },
//   { type: 'integer', value: '234' },
//   { type: 'decimal', value: '.' },
//   { type: 'fraction', value: '567' }
// ]

// Format range
const start = new Decimal('100');
const end = new Decimal('200');
const rangeFormatted = FormatNumericRange(internalSlots, start, end);
console.log(rangeFormatted); // '100–200'

NumberFormat Initialization

Initializes NumberFormat instances with locale and options processing.

/**
 * Initializes a NumberFormat instance with locale and options
 * @param nf - NumberFormat instance to initialize
 * @param locales - Locale or array of locales
 * @param opts - NumberFormat options
 * @param options - Additional configuration for initialization
 */
function InitializeNumberFormat(
  nf: Intl.NumberFormat,
  locales: string | string[] | undefined,
  opts: NumberFormatOptions | undefined,
  options: {
    getInternalSlots: (nf: Intl.NumberFormat) => NumberFormatInternal;
    localeData: Record<string, any>;
    availableLocales: Set<string>;
    currencyDigitsData: Record<string, number>;
    numberingSystemNames: Set<string>;
  }
): void;

Pattern Processing

Functions for processing number patterns and creating formatted parts.

/**
 * Partitions a number into formatted parts according to pattern
 * @param internalSlots - NumberFormat internal configuration
 * @param x - Number to partition as Decimal
 * @returns Array of formatted parts
 */
function PartitionNumberPattern(
  internalSlots: NumberFormatInternal,
  x: Decimal
): NumberFormatPart[];

/**
 * Partitions a number range into formatted parts
 * @param internalSlots - NumberFormat internal configuration
 * @param x - Start of range as Decimal
 * @param y - End of range as Decimal
 * @returns Array of formatted range parts
 */
function PartitionNumberRangePattern(
  internalSlots: NumberFormatInternal,
  x: Decimal,
  y: Decimal
): NumberFormatPart[];

Digit and Unit Options

Functions for setting digit precision and unit display options.

/**
 * Sets digit-related options for NumberFormat
 * @param internalSlots - Internal slots to modify
 * @param opts - Digit options to apply
 * @param mnfdDefault - Default minimum fraction digits
 * @param mxfdDefault - Default maximum fraction digits
 * @param notation - Number notation style
 */
function SetNumberFormatDigitOptions(
  internalSlots: NumberFormatDigitInternalSlots,
  opts: NumberFormatDigitOptions,
  mnfdDefault: number,
  mxfdDefault: number,
  notation: NumberFormatNotation
): void;

/**
 * Sets unit-related options for NumberFormat
 * @param internalSlots - Internal slots to modify
 * @param opts - Unit options to apply
 * @param availableUnits - Available unit identifiers
 */
function SetNumberFormatUnitOptions(
  internalSlots: Pick<NumberFormatInternal, 'style' | 'currency' | 'currencyDisplay' | 'unit' | 'unitDisplay'>,
  opts: Pick<NumberFormatOptions, 'style' | 'currency' | 'currencyDisplay' | 'unit' | 'unitDisplay'>,
  availableUnits: readonly string[]
): void;

Rounding and Precision

Functions for handling number rounding and precision operations.

/**
 * Applies unsigned rounding mode to a number
 * @param x - Number to round
 * @param r1 - Lower rounding boundary
 * @param r2 - Upper rounding boundary
 * @param unsignedRoundingMode - Rounding mode to apply
 * @returns Rounded Decimal value
 */
function ApplyUnsignedRoundingMode(
  x: Decimal,
  r1: Decimal,
  r2: Decimal,
  unsignedRoundingMode: UnsignedRoundingModeType
): Decimal;

/**
 * Gets unsigned rounding mode from signed rounding mode and number
 * @param roundingMode - Signed rounding mode
 * @param x - Number being rounded
 * @returns Corresponding unsigned rounding mode
 */
function GetUnsignedRoundingMode(
  roundingMode: RoundingModeType,
  x: Decimal
): UnsignedRoundingModeType;

/**
 * Formats number to fixed decimal precision
 * @param x - Number to format
 * @param minFraction - Minimum fraction digits
 * @param maxFraction - Maximum fraction digits
 * @param roundingIncrement - Rounding increment
 * @param unsignedRoundingMode - Rounding mode
 * @returns Raw formatting result
 */
function ToRawFixed(
  x: Decimal,
  minFraction: number,
  maxFraction: number,
  roundingIncrement: number,
  unsignedRoundingMode: UnsignedRoundingModeType
): RawNumberFormatResult;

/**
 * Formats number to precision with significant digits
 * @param x - Number to format
 * @param minPrecision - Minimum significant digits
 * @param maxPrecision - Maximum significant digits
 * @param unsignedRoundingMode - Rounding mode
 * @returns Raw formatting result
 */
function ToRawPrecision(
  x: Decimal,
  minPrecision: number,
  maxPrecision: number,
  unsignedRoundingMode: UnsignedRoundingModeType
): RawNumberFormatResult;

Usage Examples:

import { 
  ApplyUnsignedRoundingMode,
  ToRawFixed,
  ToRawPrecision
} from "@formatjs/ecma402-abstract";

const number = new Decimal('3.14159');

// Apply rounding
const rounded = ApplyUnsignedRoundingMode(
  number,
  new Decimal('3.14'),
  new Decimal('3.15'),
  'half-even'
);
console.log(rounded.toString()); // '3.14'

// Format to fixed precision
const fixed = ToRawFixed(number, 2, 2, 1, 'half-even');
console.log(fixed);
// { roundedNumber: Decimal('3.14'), formattedString: '3.14' }

// Format to significant digits
const precision = ToRawPrecision(number, 3, 3, 'half-even');
console.log(precision);
// { roundedNumber: Decimal('3.14'), formattedString: '3.14' }

Internal Formatting Functions

Internal functions used by the NumberFormat implementation (advanced users only).

/**
 * Internal function for formatting numbers to parts with detailed options
 * @param numberResult - Processed number result
 * @param data - Locale-specific number formatting data
 * @param pl - PluralRules instance for pluralization
 * @param options - Comprehensive formatting options
 * @returns Array of formatted number parts
 * @internal
 */
function _formatToParts(
  numberResult: NumberResult,
  data: NumberFormatLocaleInternalData,
  pl: Intl.PluralRules,
  options: NumberFormatToPartsOptions
): NumberFormatPart[];

Specialized Formatting Functions

Functions for specific formatting scenarios and computations.

/**
 * Computes exponent for number formatting
 * @param internalSlots - NumberFormat internal configuration
 * @param x - Number to compute exponent for
 * @returns Computed exponent value
 */
function ComputeExponent(internalSlots: NumberFormatInternal, x: Decimal): number;

/**
 * Computes exponent for specific magnitude
 * @param internalSlots - NumberFormat internal configuration
 * @param x - Number to compute exponent for
 * @param magnitude - Magnitude value
 * @returns Computed exponent for magnitude
 */
function ComputeExponentForMagnitude(
  internalSlots: NumberFormatInternal,
  x: Decimal,
  magnitude: number
): number;

/**
 * Gets currency digits for currency code
 * @param c - Currency code
 * @param options - Currency digits data
 * @returns Number of digits for currency
 */
function CurrencyDigits(
  c: string,
  options: { currencyDigitsData: Record<string, number> }
): number;

/**
 * Collapses number range parts for optimization
 * @param result - Array of number format parts to collapse
 * @returns Collapsed array of parts
 */
function CollapseNumberRange(result: NumberFormatPart[]): NumberFormatPart[];

/**
 * Formats number approximately with rounding indicators
 * @param internalSlots - NumberFormat internal configuration
 * @param result - Array of formatted parts
 * @returns Array of parts with approximation indicators
 */
function FormatApproximately(
  internalSlots: NumberFormatInternal,
  result: NumberFormatPart[]
): NumberFormatPart[];

Type Definitions

Key types for number formatting operations.

type NumberFormatNotation = 'standard' | 'scientific' | 'engineering' | 'compact';

type RoundingModeType = 
  | 'ceil' 
  | 'floor' 
  | 'expand' 
  | 'trunc' 
  | 'halfCeil' 
  | 'halfFloor' 
  | 'halfExpand' 
  | 'halfTrunc' 
  | 'halfEven';

type UnsignedRoundingModeType = 
  | 'infinity' 
  | 'zero' 
  | 'half-infinity' 
  | 'half-zero' 
  | 'half-even';

type UseGroupingType = 'min2' | 'auto' | 'always' | boolean;

interface NumberFormatDigitOptions {
  minimumIntegerDigits?: number;
  minimumSignificantDigits?: number;
  maximumSignificantDigits?: number;
  minimumFractionDigits?: number;
  maximumFractionDigits?: number;
  roundingPriority?: RoundingPriorityType;
  roundingIncrement?: number;
  roundingMode?: RoundingModeType;
  trailingZeroDisplay?: TrailingZeroDisplay;
}

interface NumberFormatPart {
  type: NumberFormatPartTypes;
  value: string;
  source?: string;
}

interface RawNumberFormatResult {
  roundedNumber: Decimal;
  formattedString: string;
}

interface NumberFormatInternal {
  locale: string;
  dataLocale: string;
  style: 'decimal' | 'currency' | 'percent' | 'unit';
  currency?: string;
  currencyDisplay?: 'code' | 'symbol' | 'narrowSymbol' | 'name';
  unit?: string;
  unitDisplay?: 'short' | 'narrow' | 'long';
  notation: NumberFormatNotation;
  compactDisplay?: 'short' | 'long';
  useGrouping: UseGroupingType;
  signDisplay: 'auto' | 'never' | 'always' | 'exceptZero';
  minimumIntegerDigits: number;
  minimumFractionDigits: number;
  maximumFractionDigits: number;
  minimumSignificantDigits?: number;
  maximumSignificantDigits?: number;
  roundingPriority: RoundingPriorityType;
  roundingIncrement: number;
  roundingMode: RoundingModeType;
  trailingZeroDisplay: TrailingZeroDisplay;
}

interface NumberFormatDigitInternalSlots {
  minimumIntegerDigits: number;
  minimumSignificantDigits: number;
  maximumSignificantDigits: number;
  roundingType: NumberFormatRoundingType;
  minimumFractionDigits: number;
  maximumFractionDigits: number;
  notation: NumberFormatNotation;
  roundingIncrement: number;
  roundingMode: RoundingModeType;
  trailingZeroDisplay: TrailingZeroDisplay;
  roundingPriority: RoundingPriorityType;
}

type RoundingPriorityType = 'auto' | 'morePrecision' | 'lessPrecision';

type NumberFormatRoundingType = 
  | 'morePrecision' 
  | 'lessPrecision' 
  | 'significantDigits' 
  | 'fractionDigits';

type TrailingZeroDisplay = 'auto' | 'stripIfInteger';

type NumberFormatPartTypes =
  | 'compact'
  | 'currency'
  | 'decimal'
  | 'exponentInteger'
  | 'exponentMinusSign'
  | 'exponentSeparator'
  | 'fraction'
  | 'group'
  | 'infinity'
  | 'integer'
  | 'literal'
  | 'minusSign'
  | 'nan'
  | 'percentSign'
  | 'plusSign'
  | 'unit'
  | 'unknown';

interface NumberRangeToParts {
  type: NumberFormatPartTypes;
  value: string;
  source?: 'startRange' | 'endRange' | 'shared';
}

interface NumberFormatToPartsOptions {
  numberingSystem: string;
  useGrouping?: UseGroupingType;
  style: 'decimal' | 'currency' | 'percent' | 'unit';
  notation: NumberFormatNotation;
  compactDisplay?: 'short' | 'long';
  signDisplay: 'auto' | 'never' | 'always' | 'exceptZero';
  unit?: string;
  unitDisplay?: 'short' | 'narrow' | 'long';
  currency?: string;
  currencyDisplay?: 'code' | 'symbol' | 'narrowSymbol' | 'name';
  currencySign?: 'standard' | 'accounting';
  localeMatcher: 'lookup' | 'best fit';
  minimumFractionDigits: number;
  maximumFractionDigits: number;
  minimumIntegerDigits: number;
  minimumSignificantDigits?: number;
  maximumSignificantDigits?: number;
  roundingMode: RoundingModeType;
  roundingIncrement: number;
  trailingZeroDisplay: TrailingZeroDisplay;
  roundingPriority: RoundingPriorityType;
}

interface NumberResult {
  formattedString: string;
  roundedNumber: Decimal;
  integerDigitsCount: number;
  groupedInteger: string;
}