Skip to content

Rational is rational numbers library written in JavaScript

License

Notifications You must be signed in to change notification settings

EricRovell/rational

Repository files navigation

Set of rational numbers symbol

Rational

Rational is JavaScript library for rational numbers manipulations.

Features

  • Build-in Types;
  • Dependency-free;
  • Extendable;
  • Feature rich;
  • Immutable;
  • Simple chainable API;
  • Types included;
  • Works in a browser and Node.js;

Getting started

Package available via npm:

npm i @ericrovell/rational
import { rational } from "@ericrovell/rational";

rational(2, 3).toString();            // -> "2/3"
rational([ 2, 3] ).toString();        // -> "2/3"
rational({ n: 2, d: 3 }).toString();  // -> "2/3"

Parsing

rational(input)

Parses the given input and created a new Rational instance.

rational(1, 2);
rational(0.5);
rational([ 1, 2 ]);
rational([ 1 ]);
rational({ n: 1, d: 2 });
rational("1/2");
rational("-1/2");
rational("+3/-2");
rational(".(1)");
rational("-0.1(2)");
rational("1.23(456)");
rational("1.12'5''");
rational("7'5''");

Supported input

(n?: int = 0, d?: int = 1)

Parses the given input from two integer arguments and returns a new Rational instance.

rational(1, 2); // 1/2
rational(5);    // 5/1
(input: float)

Parses the given float and returns a new Rational instance.

rational(0.5); // 1/2
(input: [ n: int = 0, d?: int = 1 ])

Parses the given ratio from (2-integer tuple) and returns a new Rational instance.

rational([]);        // 0/1
rational([ 2 ]);     // 2/1
rational([ 1, 2 ]);  // 1/2
(input: { int?: number = 0, n: int, d?: int = 1 })

Parses the given Fraction object and returns a new Rational instance.

rational({ n: -1, d: 2 });          // -1/2
rational({ int: -1, n: 2, d: 3 });  // -1 2/3

Note: integral part if specified determines the sign of the result.

rational({ int: -1, n: -2, d: 3 });  // -1 2/3
(input: StringFraction)

Parses the given fractional string in form {sign?}{int?} {sign?}{numerator}/{sign?}{denominator} and returns a new Rational instance.

rational("1/2");    // 1/2
rational("1 1/2");  // 1 1/2
rational("-2 1/4"); // -2 1/4

Note: integral part if specified determines the sign of the result.

rational("-2 -1/4"); // -2 1/4
(input: RepeatingDecimal)

Parses the given RepeatingDecimal object and returns a new Rational instance.

rational({ sign: -1, int: 1, nonrepeat: "2", repeat: "3" }); //  -7/30
rational({ repeat: 5 });                                     // 5/9
(input: StringRepeatingDecimal)

Parses the given repeating decimal string in form {sign?}{int?}.{non-repeating}?({repeating}) and returns a new Rational instance.

rational(".(1)");    //  1/9
rational("-0.1(2)"); // -2/15
(input: Degrees)

Parses the given Degrees object and returns a new Rational instance.

rational({ deg: 1, min: 1, sec: 1 }); // 3661/3600
rational({ sec: 7 });                 // 7/60
(input: StringDegrees)

Parses the given degrees string in form {sign?}{degrees?}.{minutes'?}{seconds''?} and returns a new Rational instance.

rational("1.12'5''") //  173/144
rational("-1.2'5''") // -149/144
rational("7'5''")    //   17/144
rational("-2'5''")   //   -5/144

API

.abs

Returns the absolute value of the rational number as new Rational instance.

rational(0, 2).abs.toString();   // -> "0/2"
rational(-1, 2).abs.toString();  // -> "1/2"
rational(1, -2).abs.toString();  // -> "1/2"
rational(-1, -2).abs.toString(); // -> "1/2"
rational(1, 2).abs.toString();   // -> "1/2"
.add(Rational | Input)

Performs the addition and returns the sum as new Rational instance.

rational(1, 2)
  .add(1, 4)
  .toString(); // -> "3/4"

rational(1, 2)
  .add(rational(1, 4))
  .toString(); // -> "3/4"
.ceil(places = 0)

Returns the rational number rounded up to the next largest decimal place.

rational(29, 7).ceil() // -> 5
rational(29, 7).ceil(1) // -> 4.2
rational(29, 7).ceil(2) // -> 4.15
.compare(Rational | Input)

Compares the rational number with another. Results are interpreted as:

- comparable is greater ->  1;
- comparable is smaller -> -1;
- comparable is equal   ->  0.
rational(1, 2).compare(2, 4); // ->  0
rational(1, 2).compare(3, 4); // -> -1
rational(1, 2).compare(1, 4); // ->  1

Non-strict inequalities can be performed as such:

rational.compare(1/2) >= 0 the same as >=
rational.compare(1/2) <= 0 the same as <=
.continued

Returns the continued fraction representation of the rational. The first element holds the integral part.

rational(415, 93).continued // -> [ 4, 2, 6, 7 ]
.denominator

Returns the denominator value of the rational number.

rational(1, 2).denominator; // -> 2
.div(Rational | Input)

Performs the division and returns the quotient as new Rational instance.

rational(1, 2)
  .div(1, 4)
  .toString(); // -> "2/1"

rational(1, 2)
  .div(rational(1, 4))
  .toString(); // -> "2/1"
.divisible(Rational | Input)

Checks if two rational numbers are divisible.

rational(1, 2).divisible(1, 4) // -> true
rational(5, 8).divisible(2, 7) // -> false
.floor(places = 0)

Returns the rational number rounded down to the next smallest or equal decimal place.

rational(29, 7).floor() // -> 4
rational(29, 7).floor(1) // -> 4.1
rational(29, 7).floor(2) // -> 4.14
.fractionalPart

Returns the fractional part of the rational number as a new Rational instance.

rational(1, 2).fractionalPart.toString(); // -> "1/2"
rational(3, 2).fractionalPart.toString(); // -> "1/2"
.gcd(Rational | Input)

Calculates the GCD of two rational numbers and returns a new Rational instance.

rational(5, 8).gcd(3, 7) // 1/56
rational(2, 3).gcd(7, 5) // 1/15
.integralPart

Returns the integral part of the rational number.

rational(1, 2).integralPart; // -> 0
rational(3, 2).integralPart; // -> 1
.lcm(Rational | Input)

Calculates the LCM of two rational numbers and returns a new Rational instance.

rational(5, 8).lcm(3, 7) // 15/1
.mathmod(Rational | Input)

Calculates the mathematical correct modulo of two rational numbers.

rational("-13/3").mathmod("7/8")   // -> 1/24
rational("-13/7").mathmod("19/11") // -> 123/77
.mod(Rational | Input)

Calculates the modulo of two rational numbers.

rational("13/3").mod("7/8").toString()   // -> "5/6"
rational("13/7").mod("19/11").toString() // -> "10/77"
.mul(Rational | Input)

Performs the multiplication and returns the product as new Rational instance.

rational(1, 2)
  .mul(1, 4)
  .toString(); // -> "1/8"

rational(1, 2)
  .mul(rational(1, 4))
  .toString(); // -> "1/8"
.numerator

Returns the numerator value of the rational number.

rational(1, 2).numerator; // -> 1
.opposite

Returns the opposite rational number as new Rational instance.

rational(0, 2).opposite.toString();   // -> "0/2"
rational(-1, 2).opposite.toString();  // -> "1/2"
rational(1, -2).opposite.toString();  // -> "1/2"
rational(-1, -2).opposite.toString(); // -> "-1/2"
rational(1, 2).opposite.toString();   // -> "-1/2"
.proper

Returns the boolean indicating if the rational number could be represented as proper fraction.

rational(1, 2).proper; // -> true;
rational(3, 2).proper; // -> false;
.pow(Rational | Input)

Calculates the exponentiation result of two rational numbers. If the result is rational returns a new Rational instance. If the result irrational the null returned instead.

rational(27).pow(2, 3)?.toString() // -> "9/1"
rational(2).pow(1, 2)?.toString()  // -> null
.reciprocal

Returns the reciprocal as new Rational instance.

rational(1, 2).reciprocal.toString(); // -> "2/1";
rational(3, 2).reciprocal.toString(); // -> "3/2";
.repeating

Returns the boolean indicating if the rational number could be represents a repeating decimal.

rational(1, 3).repeating; // -> true;
rational(1, 4).repeating; // -> false;
.round(places = 0)

Returns the rational number rounded to fixed decimal places.

rational(23, 8).round() // -> 3
rational(23, 8).round(1) // -> 2.9
rational(23, 8).round(2) // -> 2.88
.sign

Returns the sign of the rational number.

rational(0, 2).sign;   // ->  0
rational(-1, 2).sign;  // -> -1
rational(1, -2).sign;  // -> -1
rational(-1, -2).sign; // ->  1
rational(1, 2).sign;   // ->  1
.sub(Rational | Input)

Performs the subtraction and returns the difference as new Rational instance.

rational(1, 2)
  .sub(1, 4)
  .toString(); // -> "1/4"

rational(1, 2)
  .sub(rational(1, 4))
  .toString(); // -> "1/4"
.toString(proper = false, places?: number)

Returns a Ratio string representation.

rational(1, 2).toString()                  // -> "1/2";
rational("1 1/2").toString()               // -> "3/2";
rational({ int: 1, n: 1, d: 3}).toString() // -> "4/3";
rational("0.12(34)").toString()            // -> "611/4950";

To get a proper fraction string, use the first argument:

rational("1 1/2").toString(true)                    // -> "1 1/2";
rational(1, 2).toString(true)                       // -> "1/2";
rational({ int: 1, n: 1, d: 3 }).toString(true)      // -> "1 1/3";

If the second argument is provided, the decimal string is returned. The value represents number of places:

rational(1, 2).toString(false, 1)                    // -> "0.5";
rational("1 1/2").toString(false, 5)                 // -> "1.5";

In case the rational is a repeating decimal, it's representation is preserved:

rational("1 1/3").toString(false, 5)   // -> "1.(3)";
.valid

Returns a boolean indicating the parsing operation success. On failed attempt the rational number defaults to 0.

rational(1, 2).valid;  // -> true
rational("hi!").valid; // -> false
.valueOf(places = 15)

Returns a rational number decimal approximation:

rational(1, 2).valueOf()                     // -> 0.5;
rational("1 1/2").valueOf()                  // -> 1.5;
rational({ int: 1, n: 1, d: 3}).valueOf(5)   // -> 1.33333;
rational("0.12(34)").valueOf()               // -> 0.123434343434343;

Method is useful for coercion:

rational(1, 2) + rational(1, 4) // -> 0.75
+rational(1, 5) // -> 0.2

Extending

To extend the functionality for your needs, extend the parent Rational class:

import { Rational } from "@ericrovell/rational";

class RationalExtended extends Rational {
	constructor(input: Input = 0, denominator = 1) {
		super(input, denominator);
	}

	get ratio() {
		return [ this.numerator, this.denominator ];
	}
}

const instance = new RationalExtended(1, 2);
instance.ratio; // -> [ 1, 2 ]

Types

Tha package includes all necessary types useful for all possible valid input options are available for import:

export type {
	Degrees,
	Fraction,
	Ratio,
	RepeatingDecimal,
	StringDegrees,
	StringFraction,
	StringRepeatingDecimal
} from "@ericrovell/rational";

Tests

To run the tests use the npm run test command.