diff --git a/src/__tests__/fraction.spec.ts b/src/__tests__/fraction.spec.ts index 7ea9203..5a66434 100644 --- a/src/__tests__/fraction.spec.ts +++ b/src/__tests__/fraction.spec.ts @@ -227,4 +227,10 @@ describe('Fraction', () => { 'Numerator above safe limit' ); }); + + it('can convert a problematic float to a fraction', () => { + const x = 0.5717619047619048; + const y = new Fraction(x); + expect(y.valueOf()).toBeCloseTo(x); + }); }); diff --git a/src/fraction.ts b/src/fraction.ts index 69488d0..c6efccb 100644 --- a/src/fraction.ts +++ b/src/fraction.ts @@ -250,13 +250,20 @@ export class Fraction { if (!coefs.length) { throw new Error('Numerator above safe limit'); } - let n = coefs.pop()!; - let d = 1; - while (coefs.length) { - [n, d] = [d + n * coefs.pop()!, n]; + let j = 1; + while (j <= coefs.length) { + let n = coefs[coefs.length - j]; + let d = 1; + for (let i = coefs.length - j - 1; i >= 0; --i) { + [n, d] = [d + n * coefs[i], n]; + } + this.n = n; + this.d = d; + if (n <= Number.MAX_SAFE_INTEGER && d <= Number.MAX_SAFE_INTEGER) { + break; + } + j++; } - this.n = n; - this.d = d; } this.reduce(); }