UNPKG

@klayr/utils

Version:

Library containing generic utility functions for use with Klayr-related software

127 lines 3.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Q = exports.q = void 0; const constants_1 = require("./constants"); const numberToQ = (val, base) => { if (Number.isInteger(val)) { return BigInt(val) << base; } const [intStr, fractionalStr] = val.toString().split('.'); return ((BigInt(intStr) << base) + (BigInt(fractionalStr) << base) / BigInt(10) ** BigInt(fractionalStr.length)); }; const q = (val, base) => Q.fromValue(val, base); exports.q = q; class Q { constructor(val, base) { this._val = val; this._base = BigInt(base); } static fromValue(val, base) { if (val instanceof Q) { return new Q(val._val, val._base); } const bigintBase = BigInt(base); if (typeof val === 'number') { return new Q(numberToQ(val, bigintBase), bigintBase); } if (typeof val === 'bigint') { return new Q(val * constants_1.TWO ** bigintBase, bigintBase); } if (val.equals(Buffer.alloc(0))) { return new Q(BigInt(0), bigintBase); } return new Q(BigInt(`0x${val.toString('hex')}`), bigintBase); } add(n) { this._checkBase(n); return new Q(this._val + n._val, this._base); } sub(n) { this._checkBase(n); if (this._val < n._val) { throw new Error('Invalid input, output cannot be negative.'); } return new Q(this._val - n._val, this._base); } mul(n) { this._checkBase(n); return new Q((this._val * n._val) >> this._base, this._base); } div(n) { this._checkBase(n); if (n._val === constants_1.ZERO) { throw new Error('Cannot be divided by zero.'); } return new Q((this._val << this._base) / n._val, this._base); } muldiv(n, m, operation = 1) { this._checkBase(n); this._checkBase(m); if (m._val === constants_1.ZERO) { throw new Error('Cannot be divided by zero.'); } const mulResult = this._val * n._val; const scaledResult = mulResult << this._base; const divResult = scaledResult / m._val; if (operation === 1) { return new Q(this._roundDown(divResult), this._base); } return new Q(this._roundUp(divResult), this._base); } inv() { const numerator = new Q(constants_1.ONE << this._base, this._base); return numerator.div(this); } toBuffer() { return Buffer.from(this._bigintToHex(this._val), 'hex'); } eq(n) { return this._val === n._val; } lt(n) { return this._val < n._val; } lte(n) { return this._val <= n._val; } gt(n) { return this._val > n._val; } gte(n) { return this._val >= n._val; } floor() { return this._roundDown(this._val); } ceil() { return this._roundUp(this._val); } _checkBase(n) { if (this._base !== n._base) { throw new Error('Invalid input, base does not match.'); } } _roundDown(n) { return n >> this._base; } _roundUp(n) { const result = n >> this._base; if (n % (constants_1.ONE << this._base) === BigInt(0)) { return result; } return result + constants_1.ONE; } _bigintToHex(val) { if (val === BigInt(0)) { return ''; } const result = val.toString(16); if (result.length % 2 === 0) { return result; } return `0${result}`; } } exports.Q = Q; //# sourceMappingURL=q.js.map