xen-dev-utils
Version:
Utility functions used by the Scale Workshop ecosystem
494 lines (493 loc) • 14.5 kB
TypeScript
export type UnsignedFraction = {
n: number;
d: number;
};
export type FractionValue = Fraction | UnsignedFraction | number | string;
/**
* Greatest common divisor of two integers.
*
* Zero is treated as the identity element: gcd(0, x) = gcd(x, 0) = x
*
* The sign of the result is essentially random for negative inputs.
* @param a The first integer.
* @param b The second integer.
* @returns The largest integer that divides a and b.
*/
export declare function gcd(a: number, b: number): number;
export declare function gcd(a: bigint, b: bigint): bigint;
/**
* Least common multiple of two integers.
*
* Return zero if either of the arguments is zero.
*
* Satisfies a * b = gcd * lcm. See {@link gcd} for consequences on negative inputs.
* @param a The first integer.
* @param b The second integer.
* @returns The smallest integer that both a and b divide.
*/
export declare function lcm(a: number, b: number): number;
export declare function lcm(a: bigint, b: bigint): bigint;
/**
* Mathematically correct modulo.
* @param a The dividend.
* @param b The divisor.
* @returns The remainder of Euclidean division of a by b.
*/
export declare function mmod(a: number, b: number): number;
export declare function mmod(a: bigint, b: bigint): bigint;
/**
* Ceiling modulo.
* @param a The dividend.
* @param b The divisor.
* @returns The remainder of Euclidean division of a by b where b modc b === b.
*/
export declare function modc(a: number, b: number): number;
export declare function modc(a: bigint, b: bigint): bigint;
/**
*
* This class offers the possibility to calculate fractions.
* You can pass a fraction in different formats: either as two integers, an integer, a floating point number or a string.
*
* Numerator, denominator form
* ```ts
* new Fraction(numerator, denominator);
* ```
*
* Integer form
* ```ts
* new Fraction(numerator);
* ```
*
* Floating point form
* ```ts
* new Fraction(value);
* ```
*
* String form
* ```ts
* new Fraction("123.456"); // a simple decimal
* new Fraction("123/456"); // a string fraction
* new Fraction("13e-3"); // scientific notation
* ```
*/
export declare class Fraction {
/** Sign: +1, 0 or -1 */
s: number;
/** Numerator */
n: number;
/** Denominator */
d: number;
constructor(numerator: FractionValue, denominator?: number);
/**
* Validate that this fraction represents the ratio of two integers.
*/
validate(): void;
/**
* IEEE floats always have a denominator of a power of two. Reduce it out.
* If the process would produce integers too large for the Number type an approximation is used.
*/
defloat(): void;
/**
* Reduce out the common factor between the numerator and denominator.
*/
reduce(): void;
/**
* Normalize infinite denominator into 0/1.
*/
screenInfinity(): void;
/**
* Creates a string representation of a fraction with all digits.
*
* Example:
* ```ts
* new Fraction("100.'91823'").toString() // "100.'91823'"
* ```
**/
toString(): string;
/**
* Serialize the fraction to a JSON compatible object.
* @returns An object with properties 'n', and 'd' corresponding to a signed numerator and an unsigned denominator respectively.
*/
toJSON(): UnsignedFraction;
/**
* Revive a {@link Fraction} instance produced by Fraction.toJSON(). Return everything else as is.
*
* Intended usage:
* ```ts
* const data = JSON.parse(serializedData, Fraction.reviver);
* ```
*
* @param key Property name.
* @param value Property value.
* @returns Deserialized {@link Fraction} instance or other data without modifications.
* @throws An error if the numerator or denominator exceeds `Number.MAX_SAFE_INTEGER`.
*/
static reviver(key: string, value: any): any;
/**
* Returns an array of continued fraction elements.
*
* Example:
* ```ts
* new Fraction("7/8").toContinued() // [0, 1, 7]
* ```
*/
toContinued(): number[];
/**
* Calculates the absolute value.
*
* Example:
* ```ts
* new Fraction(-4).abs() // 4
* ```
**/
abs(): Fraction;
/**
* Returns a decimal representation of the fraction.
*
* Example:
* ```ts
* new Fraction("100.'91823'").valueOf() // 100.91823918239183
* ```
**/
valueOf(): number;
/**
* Returns the inverse of the fraction, numerator and denominator are exchanged.
*
* Example:
* ```ts
* new Fraction(-3, 4).inverse() // -4/3
* ```
**/
inverse(): Fraction;
/**
* Returns the additive inverse of the fraction.
*
* Example:
* ```ts
* new Fraction(-4).neg() // 4
* ```
**/
neg(): Fraction;
/**
* Returns a string-fraction representation of a Fraction object.
*
* Example:
* ```ts
* new Fraction("1.'3'").toFraction() // "4/3"
* ```
**/
toFraction(): string;
/**
* Clones the actual object.
*
* Example:
* ```ts
* new Fraction("-17.'345'").clone() // new Fraction("-17.'345'")
* ```
**/
clone(): Fraction;
/**
* Return a convergent of this fraction that is within the given absolute tolerance.
* @param epsilon Absolute tolerance for error.
*/
simplify(epsilon?: number): Fraction;
/**
* Return a convergent of this fraction that is within the given relative tolerance measured in cents.
* @param tolerance Relative tolerance measured in cents.
*/
simplifyRelative(tolerance?: number): Fraction;
/**
* Calculates the floor of a rational number.
*
* Example:
* ```ts
* new Fraction("4.'3'").floor() // 4/1
* ```
**/
floor(): Fraction;
/**
* Calculates the ceil of a rational number.
*
* Example:
* ```ts
* new Fraction("4.'3'").ceil() // 5/1
* ```
**/
ceil(): Fraction;
/**
* Rounds a rational number.
*
* Examples:
* ```ts
* new Fraction("4.'3'").floor() // 4/1
* new Fraction("4.5").floor() // 5/1
* new Fraction("4.'6'").floor() // 5/1
* ```
**/
round(): Fraction;
/**
* Rounds a rational number to a multiple of another rational number.
*
* Examples:
* ```ts
* new Fraction("0.'7'").roundTo("1/9") // 7/9
* new Fraction("0.78").roundTo("1/9") // 7/9
* new Fraction("0.8'3'").roundTo("1/9") // 8/9
* new Fraction("0.85").roundTo("1/9") // 8/9
* ```
**/
roundTo(other: FractionValue): Fraction;
/**
* Adds two rational numbers.
*
* Example:
* ```ts
* new Fraction({n: 2, d: 3}).add("14.9") // 467/30
* ```
**/
add(other: FractionValue): Fraction;
/**
* Subtracts two rational numbers.
*
* Example:
* ```ts
* new Fraction({n: 2, d: 3}).sub("14.9") // -427/30
* ```
**/
sub(other: FractionValue): Fraction;
/**
* Perform harmonic addition of two rational numbers according to the thin lens equation f⁻¹ = u⁻¹ + v⁻¹.
*
* Example:
* ```ts
* new Fraction('5/3').lensAdd('3/2') // 15/19
* ```
*/
lensAdd(other: FractionValue): Fraction;
/**
* Perform harmonic subtraction of two rational numbers u⁻¹ = f⁻¹ - v⁻¹ (rearranged thin lens equation).
*
* Example:
* ```ts
* new Fraction('15/19').lensSub('3/2') // 5/3
* ```
*/
lensSub(other: FractionValue): Fraction;
/**
* Multiplies two rational numbers.
*
* Example:
* ```ts
* new Fraction("-17.'345'").mul(3) // 5776/111
* ```
**/
mul(other: FractionValue): Fraction;
/**
* Divides two rational numbers
*
* Example:
* ```ts
* new Fraction("-17.'345'").div(3) // 5776/999
* ```
**/
div(other: FractionValue): Fraction;
/**
* Calculates the computational modulo of two rational numbers - a more precise fmod. Incorrectly processes signs.
*
* Examples:
* ```ts
* new Fraction("5/1").mod("3/1") // (5/1) % (3/1) = 2/1
* new Fraction("-5/1").mod("3/1") // -((5/1) % (3/1)) = -2/1
* ```
**/
mod(other: FractionValue): Fraction;
/**
* Calculates the mathematical modulo of two rational numbers. Correctly processes signs.
*
* Examples:
* ```ts
* new Fraction("5/1").mod("3/1") // (5/1) % (3/1) = 2/1
* new Fraction("-5/1").mod("3/1") // (-5/1) % (3/1) = (1/1) % (3/1) = 1/1
* ```
**/
mmod(other: FractionValue): Fraction;
/**
* Calculates the square root of the rational number.
*
* Examples:
* ```ts
* new Fraction("9/4").sqrt() // 3/2
* new Fraction(-1).sqrt() // null
* ```
* @returns The positive square root if it exists as a rational number.
*/
sqrt(): Fraction | null;
/**
* Calculates the fraction to some rational exponent, if possible.
*
* Examples:
* ```ts
* new Fraction("1/2").pow(2) // 1/4
* new Fraction("-1/2").pow(-3) // -8
* new Fraction("9/4").pow("3/2") // 27/8
* new Fraction("2/1").pow("1/2") // null
* ```
*/
pow(other: FractionValue): Fraction | null;
/**
* Compare two rational numbers, returns (this - other) which has the correct sign for `Array.sort()`.
*
* Examples:
* ```ts
* new Fraction("19.7").compare("98/5") // 0.1
* new Fraction("19.6").compare("98/5") // 0
* new Fraction("19.5").compare("98/5") // -0.1
* ```
**/
compare(other: FractionValue): number;
/**
* Check if two rational numbers are the same
*
* Examples:
* ```ts
* new Fraction("19.7").equals("98/5") // false
* new Fraction("19.6").equals("98/5") // true
* new Fraction("19.5").equals("98/5") // false
* ```
**/
equals(other: FractionValue): boolean;
/**
* Check if two rational numbers are divisible
* (i.e. this is an integer multiple of other)
*
* Examples:
* ```ts
* new Fraction("7.6").divisible("5/2") // false
* new Fraction("7.5").divisible("5/2") // true
* new Fraction("7/4").divisible("5/2") // false
* ```
*/
divisible(other: FractionValue): boolean;
/**
* Calculates the fractional gcd of two rational numbers. (i.e. both this and other is divisible by the result)
*
* Always returns a non-negative result.
*
* Example:
* ```ts
* new Fraction(5,8).gcd("3/7") // 1/56
* ```
*/
gcd(other: FractionValue): Fraction;
/**
* Calculates the fractional lcm of two rational numbers. (i.e. the result is divisible by both this and other)
*
* Has the same sign as the product of the rational numbers.
*
* Example:
* ```ts
* new Fraction(5,8).gcd("3/7") // 15
* ```
*/
lcm(other: FractionValue): Fraction;
/**
* Geometrically reduce a rational number until its absolute value is between 1 and the absolute value of other, i.e. geometric modulo.
* Note: Returns a positive result for a negative modulo if the required number of divisions is even.
*
* Examples:
* ```ts
* new Fraction(5, 1).geoMod(2) // 5/4
* new Fraction(1, 11).geoMod(3) // 27/11
* new Fraction(1, 11).geoMod("-1/3") // 9/11
* ```
*/
geoMod(other: FractionValue): Fraction;
/**
* Check if the rational number is 1.
*
* Examples:
* ```ts
* new Fraction(9, 9).isUnity() // true
* new Fraction("0.01e2").isUnity() // true
* new Fraction(7, 6).isUnity() // false
* ```
*/
isUnity(): boolean;
/**
* Calculates the geometric absolute value. Discards sign.
*
* Examples:
* ```ts
* new Fraction(3, 2).gabs() // 3/2
* new Fraction(2, 3).gabs() // 2/3
* new Fraction(-1, 2).gabs() // 2/1
* ```
**/
gabs(): Fraction;
/**
* Calculate the greatest common radical between two rational numbers if it exists.
*
* Never returns a subunitary result.
*
* Treats unity as the identity element: gcr(1, x) = gcr(x, 1) = x
*
* Examples:
* ```ts
* new Fraction(8).gcr(4) // 2
* new Fraction(81).gcr(6561) // 9
* new Fraction("1/2").gcr("1/3") // null
* ```
*/
gcr(other: FractionValue, maxIter?: number): Fraction | null;
/**
* Calculate the logarithm of a rational number in the base of another, i.e. logdivision if the result exists as a rational number.
*
* Examples:
* ```ts
* new Fraction(4).log(2) // 2
* new Fraction(64,27).log("16/9") // 3/2
* new Fraction(64,27).log("1/1") // null
* new Fraction(64,27).log(7) // null
*
* new Fraction(64,27).log("-16/9") // null
* new Fraction(-64,27).log("16/9") // null
* new Fraction(-64,27).log("-16/9") // null
* ```
*/
log(other: FractionValue, maxIter?: number): Fraction | null;
/**
* Calculate the least common radicand between two rational numbers if it exists.
*
* If either of the inputs is unitary returns unity (1).
*
* Returns a subunitary result if only one of the inputs is subunitary, superunitary otherwise.
*
* Examples:
* ```ts
* new Fraction(8).lcr(4) // 64
* new Fraction("1/2").lcr("1/3") // null
* ```
*/
lcr(other: FractionValue, maxIter?: number): Fraction | null;
/**
* Rounds a rational number to a power of another rational number.
*
* Examples:
* ```ts
* new Fraction('5/4').geoRoundTo("9/8") // 81/64
* new Fraction('5/4').geoRoundTo("1/1") // 1/1
*
* // handling negative values
*
* new Fraction('5/4').geoRoundTo("-9/8") // 81/64
*
* new Fraction('10/7').geoRoundTo("9/8") // 729/512
* new Fraction('10/7').geoRoundTo("-9/8") // 6561/4096
*
* new Fraction('-5/4').geoRoundTo("9/8") // null
*
* new Fraction('-5/4').geoRoundTo("-9/8") // -9/8
* ```
*/
geoRoundTo(other: FractionValue): Fraction | null;
}