@codercito/numeric
v1.0.0
Published
Operaciones aritméticas con precisión exacta en JavaScript. Adaptado de currency.js sin la lógica de moneda.
Maintainers
Readme
@codercito/numeric
Operaciones aritméticas con precisión exacta en JavaScript. Resuelve los problemas clásicos de coma flotante (0.1 + 0.2 !== 0.3) trabajando internamente con enteros escalados.
Adaptado de currency.js por Jason Wilson, removiendo la lógica específica de moneda.
Instalación
npm install @codercito/numericUso básico
import numeric from '@codercito/numeric';
numeric(0.1).add(0.2).value; // 0.3 (no 0.30000000000000004)
numeric(10).subtract(2.5).value; // 7.5
numeric(1.23).multiply(3).value; // 3.69
numeric(10).divide(3).value; // 3.33Se puede usar con o sin new:
numeric(5); // funciona
new numeric(5); // también funcionaConstructor
numeric(value, opts?)
| Parámetro | Tipo | Descripción |
|---|---|---|
| value | number \| string \| numeric | Valor inicial |
| opts | object (opcional) | Opciones de configuración |
Opciones:
| Opción | Tipo | Default | Descripción |
|---|---|---|---|
| precision | number | 2 | Cantidad de decimales |
| separator | string | ',' | Separador de miles para format() |
| decimal | string | '.' | Separador decimal |
| errorOnInvalid | boolean | false | Lanza error con entradas no reconocidas |
Tipos de entrada aceptados:
numeric(123.45); // número
numeric('123.45'); // string simple
numeric('1,234.56'); // string con separador de miles
numeric('$1,234.56'); // ignora caracteres no numéricos
numeric('(1.99)'); // paréntesis = negativo → -1.99
numeric('-1.99'); // negativo explícito
numeric(otraInstancia); // copia desde otra instanciaPropiedades
.value
El valor numérico como decimal.
numeric(1.23).value; // 1.23.intValue
El valor escalado como entero según la precisión.
numeric(1.23).intValue; // 123
numeric(1.23, { precision: 4 }).intValue; // 12300Métodos de operación
Todos devuelven una nueva instancia (inmutables) y son encadenables.
.add(number)
numeric(5).add(3).value; // 8
numeric(0.1).add(0.2).value; // 0.3
numeric(5).add('3.50').value; // 8.5
numeric(5).add(numeric(3)).value; // 8.subtract(number)
numeric(10).subtract(3).value; // 7
numeric(0.3).subtract(0.1).value; // 0.2.multiply(number)
numeric(1.23).multiply(3).value; // 3.69
numeric(0.1).multiply(0.1).value; // 0.01.divide(number)
numeric(10).divide(2).value; // 5
numeric(10).divide(3).value; // 3.33 (redondeado a la precisión)⚠️ La división por cero no lanza error: devuelve
Infinity,-InfinityoNaN.
Encadenamiento
const total = numeric(100)
.add(50)
.subtract(25)
.multiply(2)
.divide(5);
total.value; // 50Métodos de extracción
.integerPart()
numeric(1.23).integerPart(); // 1
numeric(45.67).integerPart(); // 45
numeric(-1.23).integerPart(); // -1.decimalPart()
Devuelve la parte decimal como entero, no como fracción.
numeric(1.23).decimalPart(); // 23
numeric(45.67).decimalPart(); // 67
numeric(100).decimalPart(); // 0Métodos de salida
.toString()
Sin separador de miles.
numeric(1234.5).toString(); // "1234.50".format(options?)
Con separador de miles y decimal.
numeric(1234.5).format(); // "1,234.50"
numeric(1234.5, { separator: '.', decimal: ',' }).format(); // "1.234,50"
numeric(1234.5).format({ separator: ' ', decimal: ',' }); // "1 234,50"
// Con función personalizada
numeric(1234.5).format((n, s) => `[${n.value}]`); // "[1234.5]".toJSON()
JSON.stringify({ total: numeric(19.99) }); // '{"total":19.99}'Ejemplos prácticos
Total de un carrito
const items = [
{ precio: 19.99, cantidad: 2 },
{ precio: 5.50, cantidad: 3 }
];
const total = items.reduce(
(acc, it) => acc.add(numeric(it.precio).multiply(it.cantidad)),
numeric(0)
);
total.format(); // "56.48"Aplicar descuento e impuesto
const subtotal = numeric(100);
const descuento = subtotal.multiply(0.10);
const conDescuento = subtotal.subtract(descuento);
const impuesto = conDescuento.multiply(0.18);
const total = conDescuento.add(impuesto);
total.format(); // "106.20"Notas
Precisión
JavaScript tiene un límite seguro de Number.MAX_SAFE_INTEGER (≈ 9 × 10¹⁵). Como la librería escala internamente por 10^precision:
| Precisión | Valor máximo seguro aprox. | |---|---| | 2 | ±9 × 10¹³ | | 4 | ±9 × 10¹¹ | | 6 | ±9 × 10⁹ |
Inmutabilidad
const a = numeric(10);
const b = a.add(5);
a.value; // 10 (no cambió)
b.value; // 15 (nueva instancia)Licencia
MIT — Basado en currency.js © Jason Wilson.
