Skip to content
markpaper

src/history/decimal.test.ts

v0.3.0 · 1.8 KB

Download file
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);
  });
});
All files