UNPKG

tough-rational

Version:

Rational class using BigInt with fallback to bignumber.js

234 lines (229 loc) 8.26 kB
'use strict'; const Rational = require('../'); const RationalFallback = require('../lib/rational-fallback'); const { expect } = require('chai'); const compat = require('../lib/compat'); const util = require('../lib/util'); if (compat.testForBigInt()) describe('rational class', () => { it('should do cmp', () => { expect(Rational(1).cmp(1)).to.eql(0); expect(Rational(0).cmp(1)).to.eql(-1); expect(Rational(1).cmp(0)).to.eql(1); }); it('should round', () => { expect(String(Rational(0.5).round())).to.eql('1'); }); it('should add', () => { const rat = new Rational(5.5).plus(5.5); expect(rat.numerator).to.eql(BigInt(11)); expect(rat.denominator).to.eql(BigInt(1)); }); it('should subtract', () => { const rat = new Rational(5.5).minus(2); expect(rat.numerator).to.eql(BigInt(7)); expect(rat.denominator).to.eql(BigInt(2)); }); it('should multiply', () => { const rat = new Rational(2.5).multiply(2.5); expect(rat.numerator).to.eql(BigInt(25)); expect(rat.denominator).to.eql(BigInt(4)); }); it('should do fp division', () => { const rat = new Rational(2.5).dividedBy(2.3); expect(rat.numerator).to.eql(BigInt(25)); expect(rat.denominator).to.eql(BigInt(23)); }); it('should do integer division', () => { const rat = new Rational(2.5).dividedToIntegerBy(2.3); expect(rat.numerator).to.eql(BigInt(1)); expect(rat.denominator).to.eql(BigInt(1)); }); it('should find absolute value', () => { const rat = new Rational(2.5).abs(); expect(rat.numerator).to.eql(BigInt(5)); expect(rat.denominator).to.eql(BigInt(2)); const otherRat = new Rational(-2.5).abs(); expect(rat.numerator).to.eql(BigInt(5)); expect(rat.denominator).to.eql(BigInt(2)); }); it('should do pow10', () => { const rat = new Rational(10).pow10(3); expect(rat.numerator).to.eql(BigInt(10000)); }); it('should do div10', () => { const rat = new Rational(10).div10(3); expect(rat.numerator).to.eql(BigInt(1)); expect(rat.denominator).to.eql(BigInt(100)); }); it('should exponentiate', () => { const rat = new Rational(10).pow(2); expect(rat.numerator).to.eql(BigInt(100)); expect(rat.denominator).to.eql(BigInt(1)); }); it('should serialize to a string', () => { const rat = new Rational(5.5); expect(String(rat)).to.eql('5.5'); }); it('should mod', () => { const rat = new Rational(3.6); expect(String(rat.mod(3))).to.eql('0.6'); }); it('should do comparison operators', () => { const a = new Rational(3.6); const b = new Rational(4.2); expect(a.gt(b)).to.be.false; expect(a.gt(3.6)).to.be.false; expect(a.gt(3.5)).to.be.true; expect(a.lt(b)).to.be.true; expect(a.lt(3.5)).to.be.false; expect(a.geq(3.5)).to.be.true; expect(a.geq(3.6)).to.be.true; expect(a.geq(3.7)).to.be.false; expect(a.leq(3.5)).to.be.false; expect(a.leq(3.6)).to.be.true; expect(a.leq(3.7)).to.be.true; expect(a.eq(3.6)).to.be.true; expect(a.eq(3.5)).to.be.false; expect(a.neq(3.6)).to.be.false; expect(a.neq(3.5)).to.be.true; expect(a.isZero()).to.be.false; expect(Rational(0).isZero()).to.be.true; expect(a.isNonZero()).to.be.true; expect(Rational(0).isNonZero()).to.be.false; expect(a.gtZero()).to.be.true; expect(a.ltZero()).to.be.false; expect(Rational(-1).gtZero()).to.be.false; expect(Rational(-1).ltZero()).to.be.true; }); it('should tell if it\'s floating point', () => { expect(Rational(1.5).isFloatingPoint()).to.be.true; expect(Rational(1).isFloatingPoint()).to.be.false; }); it('should do floor and ceil', () => { expect(String(Rational(1.5).ceil())).to.eql('2'); expect(String(Rational(1.5).floor())).to.eql('1'); }); it('should do a shift left', () => { expect(String(Rational(1).shiftLeft(2))).to.eql('4'); }); it('should do a shift right', () => { expect(Rational(256).shiftRight(2).eq(64)).to.be.true; }); it('should do a toHexString', () => { expect(Rational(4096).toHexString()).to.eql('0x1000'); }); }); describe('rational fallback class', () => { it('should add', () => { const rat = new RationalFallback(5.5).plus(5.5); expect(String(rat)).to.eql('11'); }); it('should subtract', () => { const rat = new RationalFallback(5.5).minus(2); expect(String(rat)).to.eql('3.5'); }); it('should multiply', () => { const rat = new RationalFallback(2.5).multiply(2.5); expect(String(rat)).to.eql('6.25'); }); it('should do fp division', () => { const rat = new RationalFallback(5.76).dividedBy(4.8); expect(String(rat)).to.eql('1.2'); }); it('should do integer division', () => { const rat = new RationalFallback(2.5).dividedToIntegerBy(2.3); expect(String(rat)).to.eql('1'); }); it('should find absolute value', () => { const rat = new RationalFallback(2.5).abs(); expect(String(rat)).to.eql('2.5'); const otherRat = new RationalFallback(-2.5).abs(); expect(String(otherRat)).to.eql('2.5'); }); it('should do pow10', () => { const rat = new RationalFallback(10).pow10(3); expect(String(rat)).to.eql('10000'); }); it('should do div10', () => { const rat = new RationalFallback(10).div10(3); expect(String(rat)).to.eql('0.01'); }); it('should exponentiate', () => { const rat = new RationalFallback(10).pow(2); expect(String(rat)).to.eql('100'); }); it('should serialize to a string', () => { const rat = new RationalFallback(5.5); expect(String(rat)).to.eql('5.5'); }); it('should mod', () => { const rat = new RationalFallback(3.6); expect(String(rat.mod(3))).to.eql('0.6'); }); it('should do comparison operators', () => { const a = new RationalFallback(3.6); const b = new RationalFallback(4.2); expect(a.gt(b)).to.be.false; expect(a.gt(3.6)).to.be.false; expect(a.gt(3.5)).to.be.true; expect(a.lt(b)).to.be.true; expect(a.lt(3.5)).to.be.false; expect(a.geq(3.5)).to.be.true; expect(a.geq(3.6)).to.be.true; expect(a.geq(3.7)).to.be.false; expect(a.leq(3.5)).to.be.false; expect(a.leq(3.6)).to.be.true; expect(a.leq(3.7)).to.be.true; expect(a.eq(3.6)).to.be.true; expect(a.eq(3.5)).to.be.false; expect(a.neq(3.6)).to.be.false; expect(a.neq(3.5)).to.be.true; expect(a.isZero()).to.be.false; expect(RationalFallback(0).isZero()).to.be.true; expect(a.isNonZero()).to.be.true; expect(RationalFallback(0).isNonZero()).to.be.false; expect(a.gtZero()).to.be.true; expect(a.ltZero()).to.be.false; expect(RationalFallback(-1).gtZero()).to.be.false; expect(RationalFallback(-1).ltZero()).to.be.true; }); it('should tell if it\'s floating point', () => { expect(RationalFallback(1.5).isFloatingPoint()).to.be.true; expect(RationalFallback(1).isFloatingPoint()).to.be.false; }); it('should do floor and ceil', () => { expect(String(RationalFallback(1.5).ceil())).to.eql('2'); expect(String(RationalFallback(1.5).floor())).to.eql('1'); }); it('should do a shift left', () => { expect(String(RationalFallback(1).shiftLeft(2))).to.eql('4'); }); it('should do a shift right', () => { expect(RationalFallback(256).shiftRight(2).eq(64)).to.be.true; }); it('should do a toHexString', () => { expect(RationalFallback(4096).toHexString()).to.eql('0x1000'); }); it('should do toHexStringStripped', () => { expect(RationalFallback(256).toHexStringStripped()).to.eql('0x100'); }); it('should do toHexString on a large int', () => { expect(String(RationalFallback(String(29000000000000)).toHexString())).to.eql('0x1a6016b2d000'); }); it('should do round', () => { expect(String(RationalFallback('0.5').round())).to.eql('1'); }); it('should do cmp', () => { expect(RationalFallback(1).cmp(1)).to.eql(0); expect(RationalFallback(0).cmp(1)).to.eql(-1); expect(RationalFallback(1).cmp(0)).to.eql(1); }); }); describe('rational utilities', () => { it('should padLeft', () => { const padTo = 8; const padChar = '0'; const fn = util.leftPad(padChar)(padTo); expect(fn(Array(5).join(padChar))).to.eql(Array(padTo + 1).join(padChar)); }); });