import '../../../globals.js';
// Copyright 2023-2024, University of Colorado Boulder
/**
 * Contains an import-style snippet of shader code, with dependencies on other snippets.
 *
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 */
import { alpenglow } from '../imports.js';
class BigRational {
    constructor(numerator, denominator) {
        this.numerator = BigInt(numerator);
        this.denominator = BigInt(denominator);
        if (denominator === 0n) {
            throw new Error('Division by zero');
        }
        if (denominator < 0n) {
            this.numerator = -this.numerator;
            this.denominator = -this.denominator;
        }
    }
    copy() {
        return new BigRational(this.numerator, this.denominator);
    }
    // lazy implementation NOT meant to be in JS due to excess reduction
    plus(rational) {
        return new BigRational(this.numerator * rational.denominator + this.denominator * rational.numerator, this.denominator * rational.denominator).reduced();
    }
    // lazy implementation NOT meant to be in JS due to excess reduction
    minus(rational) {
        return new BigRational(this.numerator * rational.denominator - this.denominator * rational.numerator, this.denominator * rational.denominator).reduced();
    }
    // lazy implementation NOT meant to be in JS due to excess reduction
    times(rational) {
        return new BigRational(this.numerator * rational.numerator, this.denominator * rational.denominator).reduced();
    }
    // lazy implementation NOT meant to be in JS due to excess reduction
    dividedBy(rational) {
        return new BigRational(this.numerator * rational.denominator, this.denominator * rational.numerator).reduced();
    }
    reduce() {
        if (this.numerator === 0n) {
            this.denominator = 1n;
            return;
        }
        else if (this.denominator === 1n) {
            return;
        }
        const absNumerator = this.numerator < 0n ? -this.numerator : this.numerator;
        const gcd = BigRational.gcdBigInt(absNumerator, this.denominator);
        if (gcd !== 1n) {
            this.numerator /= gcd;
            this.denominator /= gcd;
        }
    }
    reduced() {
        const result = this.copy();
        result.reduce();
        return result;
    }
    isZero() {
        return this.numerator === 0n;
    }
    isNegative() {
        return this.numerator < 0n;
    }
    isPositive() {
        return this.numerator > 0n;
    }
    ratioTest() {
        if (this.numerator === 0n || this.numerator === this.denominator) {
            return 1;
        }
        else if (this.numerator > 0n && this.numerator < this.denominator) {
            return 2;
        }
        else {
            return 0;
        }
    }
    equalsCrossMul(other) {
        return this.numerator * other.denominator === this.denominator * other.numerator;
    }
    compareCrossMul(other) {
        const thisCross = this.numerator * other.denominator;
        const otherCross = this.denominator * other.numerator;
        return thisCross < otherCross ? -1 : thisCross > otherCross ? 1 : 0;
    }
    // NOT for WGSL, slow
    equals(other) {
        const thisReduced = this.reduced();
        const otherReduced = other.reduced();
        return thisReduced.numerator === otherReduced.numerator && thisReduced.denominator === otherReduced.denominator;
    }
    // TODO: better way to do this?
    toFloat(precision = Number.MAX_SAFE_INTEGER) {
        return Number(this.numerator * BigInt(precision) / this.denominator) / precision;
    }
    toString() {
        return this.denominator === 1n ? `${this.numerator}` : `${this.numerator}/${this.denominator}`;
    }
    static whole(numerator) {
        return new BigRational(numerator, 1n);
    }
    static inverse(numerator) {
        return new BigRational(1n, numerator);
    }
    static gcdBigInt(a, b) {
        while (b !== 0n) {
            const t = b;
            b = a % b;
            a = t;
        }
        return a;
    }
}
BigRational.ZERO = new BigRational(0n, 1n);
BigRational.ONE = new BigRational(1n, 1n);
export default BigRational;
alpenglow.register('BigRational', BigRational);
//# sourceMappingURL=BigRational.js.map