Skip to content

Fraction API

RMT Compose uses Fraction.js for arbitrary-precision rational arithmetic. This ensures exact calculations without floating-point rounding errors.

DSL vs Legacy Syntax

The DSL provides a simplified way to work with fractions:

DSLLegacy JavaScript
(3/2)new Fraction(3, 2)
440new Fraction(440)
a + ba.add(b)
a - ba.sub(b)
a * ba.mul(b)
a / ba.div(b)
a ^ ba.pow(b)

Creating Fractions

Integer

440    // 440/1
0      // 0/1
-5     // -5/1
Legacy JavaScript syntax
javascript
new Fraction(440)    // 440/1
new Fraction(0)      // 0/1
new Fraction(-5)     // -5/1

Rational

(3/2)    // 3/2 (perfect fifth)
(5/4)    // 5/4 (major third)
(-1/4)   // -1/4
Legacy JavaScript syntax
javascript
new Fraction(3, 2)   // 3/2 (perfect fifth)
new Fraction(5, 4)   // 5/4 (major third)
new Fraction(-1, 4)  // -1/4

Large Numbers

Arbitrary precision is supported:

Legacy JavaScript syntax
javascript
new Fraction(123456789, 987654321)
new Fraction("355", "113")  // Approximation of pi

Arithmetic Operations

Addition: + / .add()

Adds two fractions:

(1/2) + (1/3)    // 5/6
440 + 20         // 460
Legacy JavaScript syntax
javascript
new Fraction(1, 2).add(new Fraction(1, 3))  // 5/6
new Fraction(440).add(new Fraction(20))      // 460

Subtraction: - / .sub()

Subtracts fractions:

(3/4) - (1/4)    // 2/4 = 1/2
5 - 2            // 3
Legacy JavaScript syntax
javascript
new Fraction(3, 4).sub(new Fraction(1, 4))  // 2/4 = 1/2
new Fraction(5).sub(new Fraction(2))         // 3

Multiplication: * / .mul()

Multiplies fractions:

(3/2) * (5/4)    // 15/8
440 * 2          // 880 (octave)
Legacy JavaScript syntax
javascript
new Fraction(3, 2).mul(new Fraction(5, 4))  // 15/8
new Fraction(440).mul(new Fraction(2))       // 880 (octave)

Division: / / .div()

Divides fractions:

(3/2) / 2        // 3/4
60 / 120         // 1/2 (beat duration)
Legacy JavaScript syntax
javascript
new Fraction(3, 2).div(new Fraction(2))     // 3/4
new Fraction(60).div(new Fraction(120))     // 1/2 (beat duration)

Negation: - (prefix) / .neg()

Returns the negation:

-5         // -5
-(-3/2)    // 3/2
Legacy JavaScript syntax
javascript
new Fraction(5).neg()      // -5
new Fraction(-3, 2).neg()  // 3/2

Power: ^ / .pow()

Raises to a power:

2 ^ 3         // 8 (2^3)
2 ^ (-1)      // 1/2 (2^-1)
2 ^ (1/12)    // 12-TET semitone (irrational)
Legacy JavaScript syntax
javascript
new Fraction(2).pow(new Fraction(3))      // 8 (2^3)
new Fraction(2).pow(new Fraction(-1))     // 1/2 (2^-1)
new Fraction(2).pow(new Fraction(1, 12))  // 12-TET semitone (irrational)

Irrational Results

Non-integer exponents produce irrational numbers that cannot be represented as exact fractions. RMT Compose uses SymbolicPower to preserve these algebraically where possible.

Absolute Value (Legacy Only)

Legacy JavaScript syntax
javascript
new Fraction(-5, 3).abs()  // 5/3

Inverse (Legacy Only)

Legacy JavaScript syntax
javascript
new Fraction(3, 2).inverse()  // 2/3
new Fraction(4).inverse()     // 1/4

Modulo (Legacy Only)

Legacy JavaScript syntax
javascript
new Fraction(7).mod(new Fraction(3))  // 1

Comparison Methods (Legacy Only)

Legacy JavaScript syntax

equals(other)

javascript
new Fraction(1, 2).equals(new Fraction(2, 4))  // true
new Fraction(3, 2).equals(new Fraction(3, 2))  // true

compare(other)

Returns -1, 0, or 1:

javascript
new Fraction(1, 2).compare(new Fraction(2, 3))  // -1 (less than)
new Fraction(3, 2).compare(new Fraction(3, 2))  // 0 (equal)
new Fraction(5, 4).compare(new Fraction(1))     // 1 (greater than)

Conversion Methods (Legacy Only)

Legacy JavaScript syntax

valueOf()

Returns JavaScript number (may lose precision):

javascript
new Fraction(3, 2).valueOf()  // 1.5
new Fraction(1, 3).valueOf()  // 0.3333333333333333

toString()

Returns string representation:

javascript
new Fraction(3, 2).toString()  // "3/2"
new Fraction(4).toString()     // "4"

toFraction()

Returns simplified string:

javascript
new Fraction(6, 4).toFraction()  // "3/2"

Properties (Legacy Only)

Legacy JavaScript syntax

n (numerator)

javascript
new Fraction(3, 2).n  // 3

d (denominator)

javascript
new Fraction(3, 2).d  // 2

s (sign)

javascript
new Fraction(3, 2).s   // 1
new Fraction(-3, 2).s  // -1

Common Patterns in RMT Compose

Frequency Ratios

// Perfect fifth above base
base.f * (3/2)

// Octave above
base.f * 2

// Perfect fourth below
base.f / (4/3)
Legacy JavaScript syntax
javascript
// Perfect fifth above base
module.baseNote.getVariable('frequency').mul(new Fraction(3, 2))

// Octave above
module.baseNote.getVariable('frequency').mul(new Fraction(2))

// Perfect fourth below
module.baseNote.getVariable('frequency').div(new Fraction(4, 3))

Beat Calculations

// Duration of one beat at current tempo
60 / tempo(base)

// Two beats
60 / tempo(base) * 2

// Half beat (eighth note)
60 / tempo(base) * (1/2)
Legacy JavaScript syntax
javascript
// Duration of one beat at current tempo
new Fraction(60).div(module.findTempo(module.baseNote))

// Two beats
new Fraction(60).div(module.findTempo(module.baseNote)).mul(new Fraction(2))

// Half beat (eighth note)
new Fraction(60).div(module.findTempo(module.baseNote)).mul(new Fraction(1, 2))

Sequential Timing

// Start after previous note ends
[prev].t + [prev].d
Legacy JavaScript syntax
javascript
// Start after previous note ends
module.getNoteById(prev).getVariable('startTime')
  .add(module.getNoteById(prev).getVariable('duration'))

See Also

Released under the RMT Personal Non-Commercial License