src/history/decimal.test.ts
v0.3.0 · 1.8 KB
import { describe, expect, it } from 'vitest';
import { abs, add, cmp, div, mul, parseDec, pow10Neg, requireDec, sign, sub, toNum, toStr } from './decimal.js';
const d = (s: string) => requireDec(s, 'test');
describe('decimal', () => {
it('parses HL decimal strings, numbers and exponents', () => {
expect(toStr(d('0.0'))).toBe('0');
expect(toStr(d('-12.500'))).toBe('-12.5');
expect(toStr(d('.5'))).toBe('0.5');
expect(toStr(d('1e-7'))).toBe('0.0000001');
expect(toStr(d('1.5E3'))).toBe('1500');
expect(toStr(parseDec(0.25)!)).toBe('0.25');
});
it('rejects non-decimals', () => {
expect(parseDec('abc')).toBeNull();
expect(parseDec('')).toBeNull();
expect(parseDec('.')).toBeNull();
expect(parseDec(Number.NaN)).toBeNull();
expect(parseDec(null)).toBeNull();
expect(parseDec('1e999')).toBeNull();
expect(() => requireDec('x', 'sz')).toThrow(/sz/);
});
it('adds exactly where floats drift', () => {
expect(0.1 + 0.2).not.toBe(0.3);
expect(toStr(add(d('0.1'), d('0.2')))).toBe('0.3');
expect(sign(sub(add(d('0.1'), d('0.2')), d('0.3')))).toBe(0);
});
it('multiplies, compares and takes abs', () => {
expect(toStr(mul(d('0.29'), d('100')))).toBe('29');
expect(cmp(d('1.10'), d('1.1'))).toBe(0);
expect(cmp(d('-2'), d('1'))).toBe(-1);
expect(toStr(abs(d('-3.25')))).toBe('3.25');
expect(toStr(pow10Neg(6))).toBe('0.000001');
expect(toStr(pow10Neg(-2))).toBe('100');
});
it('divides with half-away-from-zero rounding', () => {
expect(toStr(div(d('2'), d('3'), 4))).toBe('0.6667');
expect(toStr(div(d('-2'), d('3'), 4))).toBe('-0.6667');
expect(toStr(div(d('1'), d('8'), 2))).toBe('0.13');
expect(toStr(div(d('10.5'), d('-0.5'), 2))).toBe('-21');
expect(toNum(div(d('1'), d('4')))).toBe(0.25);
expect(() => div(d('1'), d('0'))).toThrow(RangeError);
});
});