UNPKG

ilp-protocol-stream

Version:

Interledger Transport Protocol for sending multiple streams of money and data over ILP.

102 lines 3.73 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const assert_1 = __importDefault(require("assert")); const long_1 = __importDefault(require("long")); const long_2 = require("./long"); class Rational { constructor(numer, denom, unsigned) { if (!unsigned) { throw new Error('signed rationals are not implemented'); } assert_1.default.strictEqual(numer.unsigned, unsigned, 'numerator is incorrectly signed'); assert_1.default.strictEqual(denom.unsigned, unsigned, 'denominator is incorrectly signed'); (0, assert_1.default)(!denom.isZero(), 'denominator must be non-zero'); this.a = numer; this.b = denom; this.unsigned = unsigned; } static isRational(value) { return value instanceof Rational; } static fromNumbers(numer, denom, unsigned) { return new Rational(long_1.default.fromNumber(numer, unsigned), long_1.default.fromNumber(denom, unsigned), unsigned); } static fromNumber(value, unsigned) { if (!isFinite(value)) { throw new Error('value must be finite'); } else if (unsigned && value < 0) { throw new Error('unsigned value must be positive'); } if (value % 1 === 0) { return Rational.fromNumbers(value, 1, unsigned); } const mag = Math.floor(Math.log(value) / Math.LN10); let shift = mag < 0 ? 18 : 18 - mag; let den = 1; while (Math.floor(value * den) !== value * den && shift > 0) { den *= 10; shift--; } return Rational.fromNumbers(value * den, den, unsigned); } multiplyByLong(value) { return (0, long_2.multiplyDivideFloor)(value, this.a, this.b); } multiplyByLongCeil(value) { return (0, long_2.multiplyDivideCeil)(value, this.a, this.b); } multiplyByRational(other) { return new Rational(this.a.multiply(other.a), this.b.multiply(other.b), this.unsigned); } greaterThanOne() { return this.a.greaterThan(this.b); } complement() { if (this.a.greaterThan(this.b)) { throw new Error('cannot take complement of rational >1'); } return new Rational(this.b.subtract(this.a), this.b, this.unsigned); } reciprocal() { return new Rational(this.b, this.a, this.unsigned); } toNumber() { return this.a.toNumber() / this.b.toNumber(); } toString() { const str = trimRight(this.toFixed(19), '0'); return str[str.length - 1] === '.' ? str.slice(0, -1) : str; } toFixed(digits) { digits = digits || 0; const quotient = this.a.divide(this.b); if (digits === 0) { return quotient.toString(); } const remainder = this.a.modulo(this.b); const remainderString = (0, long_2.multiplyDivideRound)(remainder, power10(digits), this.b).toString(); return quotient.toString() + '.' + '0'.repeat(digits - remainderString.length) + remainderString; } } exports.default = Rational; Rational.UZERO = new Rational(long_1.default.UZERO, long_1.default.UONE, true); function trimRight(str, ch) { for (let i = str.length - 1; i >= 0; i--) { if (str[i] !== ch) { return str.slice(0, i + 1); } } return ''; } function power10(n) { const ten = long_1.default.fromNumber(10, true); let value = long_1.default.UONE; while (n--) value = value.multiply(ten); return value; } //# sourceMappingURL=rational.js.map