UNPKG

@technobuddha/library

Version:
106 lines (94 loc) 3.27 kB
import { type Numbering, numbering } from './numbering.ts'; import { empty, space } from './unicode.ts'; /** * Options for customizing the output and behavior of fraction number representations. * @group Math * @category Verbalization */ export type FractionOptions = { /** * Output format for the number representation. * @defaultValue 'alphabetic' */ output?: 'numeric' | 'alphabetic' | 'hybrid' | Numbering['output']; /** * Text to use for "and" in compound numbers (e.g., "one hundred and one"). * @defaultValue (empty string) */ and?: Numbering['and']; /** * Text to use for hyphens in compound numbers (e.g., "twenty-one"). * @defaultValue ' ' (space) */ hyphen?: Numbering['hyphen']; /** * Tolerance for floating-point comparison when converting decimals to fractions. * @defaultValue 0.01 */ tolerance?: Numbering['tolerance']; /** * Type of denominators to use when expressing fractions. * @defaultValue 'common' */ denominators?: Numbering['denominators']; /** * Precision for decimal/fraction conversion. * @defaultValue 9 */ precision?: Numbering['precision']; /** * Whether to output ordinal numbers (e.g., "first", "second") instead of cardinal numbers. * @defaultValue false */ ordinal?: Numbering['ordinal']; /** * Whether to shift the fractional part of the number. */ shift?: Numbering['shift']; }; /** * Converts a numeric input into a formatted fraction string, either in numeric or alphabetic form. * * The function finds the closest matching fraction from a predefined list and formats the output * based on the specified options. If the input is negative, the result is prefixed accordingly. * The output can be either a numeric representation (e.g., "1 1⁄2") or an alphabetic representation * (e.g., "one and one half"). * @param input - The number to convert to a fraction string. * @param options - An optional object specifying the output format. * @returns The formatted fraction string. * @example * ```typescript * fraction(1.5); // "one and one half" * fraction(2.75, { output: 'numeric' }); // "2 3⁄4" * fraction(-0.25, { output: 'alphabetic' }); // "negative one quarter" * fraction(0.333, { precision: 2 }); // "one third" * ``` * @group Math * @category Verbalization */ export function fraction(input: number, options: FractionOptions = {}): string { const numberingOptions: Numbering = { output: { integer: (( options?.output === 'alphabetic' || options?.output === 'numeric' || options?.output === 'hybrid' ) ? options.output : options.output?.integer) ?? 'numeric', fraction: (options?.output === 'alphabetic' || options?.output === 'numeric' ? options.output : options?.output === 'hybrid' ? 'alphabetic' : options.output?.fraction) ?? 'numeric', }, and: options?.and ?? empty, hyphen: options?.hyphen ?? space, tolerance: options?.tolerance ?? 0.01, denominators: options?.denominators ?? 'common', precision: options?.precision ?? 6, ordinal: options?.ordinal ?? false, shift: options?.shift ?? false, }; return numbering(input, numberingOptions); }