Skip to content

Commit

Permalink
Refer to infinity in Fraction error messages
Browse files Browse the repository at this point in the history
Normalize infinite denominator to zero.

ref #29
  • Loading branch information
frostburn committed Apr 26, 2024
1 parent c133dd1 commit a80a4de
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 3 deletions.
50 changes: 50 additions & 0 deletions src/__tests__/fraction.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -674,4 +674,54 @@ describe('Fraction', () => {
expect(fraction.n).toBe(0);
expect(fraction.d).toBe(1);
});

it('normalizes zero (infinite denominator)', () => {
const fraction = new Fraction({n: 123, d: Infinity});
expect(fraction.s).toBe(0);
expect(fraction.n).toBe(0);
expect(fraction.d).toBe(1);
});

it('normalizes zero (infinite second argument)', () => {
const fraction = new Fraction(-123, Infinity);
expect(fraction.s).toBe(0);
expect(fraction.n).toBe(0);
expect(fraction.d).toBe(1);
});

it('throws an informative error for (Infinity, 1)', () => {
expect(() => new Fraction(Infinity, 1)).throws(
'Cannot represent Infinity as a fraction'
);
});

it('throws an informative error for (-Infinity, 1)', () => {
expect(() => new Fraction(-Infinity, 1)).throws(
'Cannot represent Infinity as a fraction'
);
});

it('throws an informative error for Infinity', () => {
expect(() => new Fraction(Infinity)).throws(
'Cannot represent Infinity as a fraction'
);
});

it('throws an informative error for {n: Infinity, d:1}', () => {
expect(() => new Fraction({n: Infinity, d: 1})).throws(
'Cannot represent Infinity as a fraction'
);
});

it('throws for NaN (literal)', () => {
expect(() => new Fraction(NaN)).throws(
'Cannot represent NaN as a fraction'
);
});

it('throws for NaN (implicit)', () => {
expect(() => new Fraction(Infinity, Infinity)).throws(
'Cannot represent NaN as a fraction'
);
});
});
33 changes: 30 additions & 3 deletions src/fraction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,18 @@ export class Fraction {
this.s = Math.sign(numerator * denominator);
this.n = Math.abs(numerator);
this.d = Math.abs(denominator);
if (this.n > Number.MAX_SAFE_INTEGER) {
throw new Error('Numerator above safe limit');
}

this.screenInfinity();

if (this.d > Number.MAX_SAFE_INTEGER) {
throw new Error('Denominator above safe limit');
}
if (this.n > Number.MAX_SAFE_INTEGER) {
if (!isFinite(this.n)) {
throw new Error('Cannot represent Infinity as a fraction');
}
throw new Error('Numerator above safe limit');
}
if (this.d === 0) {
throw new Error('Division by Zero');
}
Expand All @@ -131,6 +137,9 @@ export class Fraction {
this.s = Math.sign(numerator);
this.n = Math.abs(numerator);
this.d = 1;
if (!isFinite(this.n)) {
throw new Error('Cannot represent Infinity as a fraction');
}
this.defloat();
} else if (typeof numerator === 'string') {
numerator = numerator.toLowerCase();
Expand Down Expand Up @@ -222,6 +231,7 @@ export class Fraction {
}
this.n = Math.abs(numerator.n);
this.d = Math.abs(numerator.d);
this.screenInfinity();
this.reduce();
}
this.validate();
Expand All @@ -235,6 +245,9 @@ export class Fraction {
throw new Error('Cannot represent NaN as a fraction');
}
if (this.n > Number.MAX_SAFE_INTEGER) {
if (!isFinite(this.n)) {
throw new Error('Cannot represent Infinity as a fraction');
}
throw new Error('Numerator above safe limit');
}
if (this.d > Number.MAX_SAFE_INTEGER) {
Expand Down Expand Up @@ -296,6 +309,20 @@ export class Fraction {
this.d /= commonFactor;
}

/**
* Normalize infinite denominator into 0/1.
*/
screenInfinity() {
if (!isFinite(this.d)) {
if (!isFinite(this.n)) {
throw new Error('Cannot represent NaN as a fraction');
}
this.s = 0;
this.n = 0;
this.d = 1;
}
}

/**
* Creates a string representation of a fraction with all digits.
*
Expand Down

0 comments on commit a80a4de

Please sign in to comment.