continuedfraction.js 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +135 -24
- package/dist/continuedfraction.d.mts +115 -0
- package/dist/continuedfraction.d.ts +16 -0
- package/dist/continuedfraction.js +248 -177
- package/dist/continuedfraction.js.map +7 -0
- package/dist/continuedfraction.min.js +8 -10
- package/dist/continuedfraction.mjs +954 -171
- package/dist/continuedfraction.mjs.map +7 -0
- package/package.json +44 -22
- package/continuedfraction.d.ts +0 -80
- package/src/continuedfraction.js +0 -179
- package/tests/continued.js +0 -50
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
[](http://opensource.org/licenses/MIT)
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
ContinuedFraction.js is published as [`continuedfraction.js`](https://www.npmjs.com/package/continuedfraction.js). It generates simple and generalized continued fractions and evaluates a bounded number of terms to an exact [Fraction.js](https://github.com/rawify/Fraction.js) convergent.
|
|
8
|
+
|
|
9
|
+
Use it to inspect continued-fraction terms or construct rational approximations of square roots, real values, rational values, φ, e, π, and 4/π. Use Fraction.js directly when the input is already rational and no term sequence is needed. It is not an arbitrary-precision transcendental-function package: each result is a rational convergent chosen by the requested term count.
|
|
8
10
|
|
|
9
11
|
## Features
|
|
10
12
|
|
|
@@ -12,15 +14,19 @@ A lightweight JavaScript library sitting on the shoulders of [Fraction.js](https
|
|
|
12
14
|
- Convert any real number or rational to its continued‑fraction
|
|
13
15
|
- Infinite generators for classic constants: φ (golden ratio), e, π, 4/π
|
|
14
16
|
- Evaluate (simple or generalized) continued fractions to a `Fraction`
|
|
17
|
+
- Enumerate exact convergents or collect a bounded number of terms
|
|
18
|
+
- Strict TypeScript types for terms, sources, and coefficients
|
|
15
19
|
|
|
16
|
-
##
|
|
20
|
+
## Quick example
|
|
21
|
+
|
|
22
|
+
```javascript
|
|
23
|
+
import ContinuedFraction from 'continuedfraction.js';
|
|
17
24
|
|
|
18
|
-
```js
|
|
19
25
|
const frac = ContinuedFraction.eval(
|
|
20
26
|
ContinuedFraction.fromFraction(3021, 203),
|
|
21
|
-
10
|
|
27
|
+
10
|
|
22
28
|
);
|
|
23
|
-
console.log(frac.
|
|
29
|
+
console.log(frac.toFraction()); // "3021/203"
|
|
24
30
|
```
|
|
25
31
|
|
|
26
32
|
## Installation
|
|
@@ -43,27 +49,115 @@ Alternatively, download or clone the repository:
|
|
|
43
49
|
git clone https://github.com/rawify/ContinuedFraction.js
|
|
44
50
|
```
|
|
45
51
|
|
|
46
|
-
## Usage
|
|
52
|
+
## Usage and runtime
|
|
53
|
+
|
|
54
|
+
`ContinuedFraction` is a static class and cannot be instantiated. Use its methods directly.
|
|
55
|
+
|
|
56
|
+
### CommonJS
|
|
57
|
+
|
|
58
|
+
```javascript
|
|
59
|
+
const ContinuedFraction = require('continuedfraction.js');
|
|
60
|
+
const terms = ContinuedFraction.toArray(ContinuedFraction.sqrt(2), 8);
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### ES modules
|
|
64
|
+
|
|
65
|
+
```javascript
|
|
66
|
+
import ContinuedFraction, { ContinuedFraction as NamedContinuedFraction } from 'continuedfraction.js';
|
|
67
|
+
const terms = ContinuedFraction.toArray(ContinuedFraction.sqrt(2), 8);
|
|
68
|
+
```
|
|
47
69
|
|
|
48
|
-
|
|
70
|
+
### Standalone browser script
|
|
49
71
|
|
|
50
72
|
```html
|
|
51
|
-
<script src="
|
|
73
|
+
<script src="https://cdn.jsdelivr.net/npm/continuedfraction.js@0.1.0/dist/continuedfraction.min.js"></script>
|
|
52
74
|
<script>
|
|
53
|
-
|
|
75
|
+
const terms = ContinuedFraction.toArray(ContinuedFraction.sqrt(2), 8);
|
|
54
76
|
</script>
|
|
55
77
|
```
|
|
56
78
|
|
|
57
|
-
|
|
79
|
+
### Native browser module
|
|
80
|
+
|
|
81
|
+
```html
|
|
82
|
+
<script type="module">
|
|
83
|
+
import ContinuedFraction from 'https://cdn.jsdelivr.net/npm/continuedfraction.js@0.1.0/dist/continuedfraction.mjs';
|
|
84
|
+
const terms = ContinuedFraction.toArray(ContinuedFraction.sqrt(2), 8);
|
|
85
|
+
</script>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
The package supports Node.js 20 or newer. Its CommonJS build uses the declared Fraction.js dependency; the ESM and standalone browser builds are self-contained. CommonJS also exposes `.default` and `.ContinuedFraction` aliases for compatibility.
|
|
89
|
+
|
|
90
|
+
## Recipes
|
|
91
|
+
|
|
92
|
+
### Approximate an irrational square root
|
|
93
|
+
|
|
94
|
+
`sqrt()` generates the periodic simple continued fraction; `eval()` consumes at most the requested number of terms.
|
|
58
95
|
|
|
59
96
|
```javascript
|
|
60
|
-
|
|
97
|
+
import ContinuedFraction from 'continuedfraction.js';
|
|
98
|
+
|
|
99
|
+
const approximation = ContinuedFraction.eval(
|
|
100
|
+
ContinuedFraction.sqrt(2),
|
|
101
|
+
8
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
console.log(approximation.toFraction()); // "577/408"
|
|
105
|
+
console.log(approximation.valueOf()); // 1.4142156862745099
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
`sqrt(N)` expects a non-negative safe integer and throws `RangeError` otherwise. Perfect squares terminate after one term; non-squares produce an infinite generator.
|
|
109
|
+
|
|
110
|
+
### Inspect and reconstruct a rational value
|
|
111
|
+
|
|
112
|
+
Rational expansions terminate. Fraction.js represents their terms as `BigInt`, so convert them before JSON serialization when the values are known to fit safely in `Number`.
|
|
113
|
+
|
|
114
|
+
```javascript
|
|
115
|
+
import ContinuedFraction from 'continuedfraction.js';
|
|
116
|
+
|
|
117
|
+
const terms = [...ContinuedFraction.fromFraction(415, 93)];
|
|
118
|
+
const restored = ContinuedFraction.eval(
|
|
119
|
+
ContinuedFraction.fromFraction(415, 93),
|
|
120
|
+
10
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
console.log(terms.map(Number)); // [4, 2, 6, 7]
|
|
124
|
+
console.log(restored.toFraction()); // "415/93"
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Do not convert large `BigInt` terms to `Number` unless they are within the safe-integer range.
|
|
128
|
+
|
|
129
|
+
### Build convergents for e and a perfect square
|
|
130
|
+
|
|
131
|
+
Generator functions can be passed directly to `eval()`. This creates a new generator for each evaluation.
|
|
132
|
+
|
|
133
|
+
```javascript
|
|
134
|
+
import ContinuedFraction from 'continuedfraction.js';
|
|
135
|
+
|
|
136
|
+
const e = ContinuedFraction.eval(ContinuedFraction.E, 10);
|
|
137
|
+
const squareTerms = [...ContinuedFraction.sqrt(49)];
|
|
138
|
+
|
|
139
|
+
console.log(e.toFraction()); // "1457/536"
|
|
140
|
+
console.log(squareTerms.map(Number)); // [7]
|
|
61
141
|
```
|
|
62
142
|
|
|
63
|
-
or
|
|
143
|
+
Always bound iteration over `E()`, `PHI()`, `PI()`, `FOUR_OVER_PI()`, or a non-square `sqrt()` generator. Spreading an infinite generator never completes.
|
|
144
|
+
|
|
145
|
+
### Inspect every convergent
|
|
146
|
+
|
|
147
|
+
`convergents()` yields exact Fraction.js values lazily. `fromTerms()` turns an existing sequence into a generator, while `toArray()` safely collects a bounded prefix.
|
|
64
148
|
|
|
65
149
|
```javascript
|
|
66
150
|
import ContinuedFraction from 'continuedfraction.js';
|
|
151
|
+
|
|
152
|
+
const convergents = ContinuedFraction.toArray(
|
|
153
|
+
ContinuedFraction.convergents(
|
|
154
|
+
ContinuedFraction.fromTerms([1, 2, 2, 2])
|
|
155
|
+
),
|
|
156
|
+
4
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
console.log(convergents.map((value) => value.toFraction()));
|
|
160
|
+
// ["1", "3/2", "7/5", "17/12"]
|
|
67
161
|
```
|
|
68
162
|
|
|
69
163
|
## ContinuedFraction API
|
|
@@ -75,30 +169,40 @@ Import the static utility class and use its generators and evaluator:
|
|
|
75
169
|
const sqrtGen = ContinuedFraction.sqrt(23);
|
|
76
170
|
console.log(sqrtGen.next().value); // 4
|
|
77
171
|
console.log(sqrtGen.next().value); // 1, 3, 1, 8, …
|
|
172
|
+
```
|
|
78
173
|
|
|
174
|
+
```javascript
|
|
79
175
|
// 2) Continued‑fraction of a decimal
|
|
80
176
|
let cnt = 0;
|
|
81
177
|
for (let piCf of ContinuedFraction.fromNumber(Math.PI)) {
|
|
82
178
|
console.log(piCf);
|
|
83
179
|
if (cnt++ >= 10) break;
|
|
84
180
|
}
|
|
181
|
+
```
|
|
85
182
|
|
|
183
|
+
```javascript
|
|
86
184
|
// 3) Golden ratio φ terms
|
|
87
185
|
const phiGen = ContinuedFraction.PHI();
|
|
88
186
|
console.log(phiGen.next().value); // 1, and forever 1…
|
|
187
|
+
```
|
|
89
188
|
|
|
189
|
+
```javascript
|
|
90
190
|
// 4) Evaluate the first 10 terms of e’s CF to a Fraction
|
|
91
191
|
const approxE = ContinuedFraction.eval(ContinuedFraction.E, 10);
|
|
92
|
-
console.log(approxE.
|
|
192
|
+
console.log(approxE.toFraction()); // "1457/536"
|
|
193
|
+
```
|
|
93
194
|
|
|
195
|
+
```javascript
|
|
94
196
|
// 5) Generalized CF for π, 4/π
|
|
95
197
|
const genPi = ContinuedFraction.PI();
|
|
96
198
|
console.log(genPi.next().value); // { a: 3, b: 0 }
|
|
97
199
|
console.log(genPi.next().value); // { a: 6, b: 1 }
|
|
200
|
+
```
|
|
98
201
|
|
|
202
|
+
```javascript
|
|
99
203
|
// 6) Continued‑fraction from two integers
|
|
100
204
|
const halfCf = ContinuedFraction.fromFraction(1, 2);
|
|
101
|
-
console.log([...halfCf]); // [
|
|
205
|
+
console.log([...halfCf]); // [0n, 2n]
|
|
102
206
|
```
|
|
103
207
|
|
|
104
208
|
### Methods
|
|
@@ -106,28 +210,35 @@ console.log([...halfCf]); // [0, 2]
|
|
|
106
210
|
| Method | Signature | Description |
|
|
107
211
|
| ------------------------ | ----------------------------------------------------------------- | ----------------------------------------------------------------------- |
|
|
108
212
|
| `sqrt(N: number)` | `Generator<number>` | Simple CF terms of √N |
|
|
109
|
-
| `fromNumber(n)` | `Generator<
|
|
110
|
-
| `fromFraction(a, b)`
|
|
213
|
+
| `fromNumber(n)` | `Generator<bigint>` | CF terms of any real via Fraction.js |
|
|
214
|
+
| `fromFraction(a, b?)` | `Generator<bigint>` | CF terms of a rational value or a/b |
|
|
215
|
+
| `fromTerms(terms)` | `Generator<Term>` | Yield an existing finite or infinite term sequence |
|
|
111
216
|
| `PHI()` | `Generator<number>` | Infinite 1’s for the golden ratio |
|
|
112
217
|
| `FOUR_OVER_PI()` | `Generator<CFTerm>` | Generalized CF terms for 4/π |
|
|
113
218
|
| `PI()` | `Generator<CFTerm>` | Generalized CF terms for π |
|
|
114
219
|
| `E()` | `Generator<number>` | CF expansion of e |
|
|
115
|
-
| `
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
As every library I publish, ContinuedFraction is also built to be as small as possible after compressing it with Google Closure Compiler in advanced mode. Thus the coding style orientates a little on maxing-out the compression rate. Please make sure you keep this style if you plan to extend the library.
|
|
220
|
+
| `toArray(source, steps)` | `Term[]` | Collect at most `steps` terms; the default is `10` |
|
|
221
|
+
| `convergents(source)` | `Generator<Fraction>` | Yield every exact convergent lazily |
|
|
222
|
+
| `eval(source, steps)` | `Fraction` | Evaluate up to `steps` terms; the default is `10` |
|
|
120
223
|
|
|
121
224
|
## Building the library
|
|
122
225
|
|
|
123
|
-
|
|
226
|
+
The source is strict TypeScript. The build emits CommonJS, ESM, a standalone browser bundle, source maps, and format-specific declarations.
|
|
124
227
|
|
|
125
|
-
|
|
228
|
+
After cloning the Git repository, run:
|
|
229
|
+
|
|
230
|
+
```bash
|
|
126
231
|
npm install
|
|
127
232
|
npm run build
|
|
128
233
|
```
|
|
129
234
|
|
|
235
|
+
Run all runtime and type-level tests with:
|
|
236
|
+
|
|
237
|
+
```bash
|
|
238
|
+
npm test
|
|
239
|
+
```
|
|
240
|
+
|
|
130
241
|
## Copyright and Licensing
|
|
131
242
|
|
|
132
|
-
Copyright (c)
|
|
243
|
+
Copyright (c) 2026, [Robert Eisele](https://raw.org/)
|
|
133
244
|
Licensed under the MIT license.
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license ContinuedFraction.js v0.1.0
|
|
3
|
+
* https://github.com/rawify/ContinuedFraction.js
|
|
4
|
+
*
|
|
5
|
+
* Copyright (c) 2026, Robert Eisele (https://raw.org/)
|
|
6
|
+
* Licensed under the MIT license.
|
|
7
|
+
**/
|
|
8
|
+
import { type Fraction as FractionValue } from 'fraction.js';
|
|
9
|
+
/** A value accepted by Fraction.js as a continued-fraction coefficient. */
|
|
10
|
+
export type Coefficient = number | string | bigint | FractionValue;
|
|
11
|
+
/** A term of a generalized continued fraction. */
|
|
12
|
+
export interface CFTerm {
|
|
13
|
+
/** The a_n coefficient. */
|
|
14
|
+
a: Coefficient;
|
|
15
|
+
/** The b_n coefficient. */
|
|
16
|
+
b: Coefficient;
|
|
17
|
+
}
|
|
18
|
+
/** A simple or generalized continued-fraction term. */
|
|
19
|
+
export type ContinuedFractionTerm = Coefficient | CFTerm;
|
|
20
|
+
/** A term iterator or a function that creates one. */
|
|
21
|
+
export type ContinuedFractionSource<T = ContinuedFractionTerm> = Iterator<T> | (() => Iterator<T>);
|
|
22
|
+
/**
|
|
23
|
+
* Utility class for generating and evaluating continued fractions.
|
|
24
|
+
* All methods are static; the class cannot be instantiated.
|
|
25
|
+
*/
|
|
26
|
+
export declare class ContinuedFraction {
|
|
27
|
+
private constructor();
|
|
28
|
+
/**
|
|
29
|
+
* Infinite generator for the continued-fraction terms of sqrt(N).
|
|
30
|
+
* sqrt(N) = [a0; (a1, a2, ..., a_p)], with a period boundary at ak = 2*a0.
|
|
31
|
+
* For perfect squares, yields only a0 = floor(sqrt(N)) and then returns.
|
|
32
|
+
*
|
|
33
|
+
* @param N Integer whose square-root CF expansion is desired (N >= 0).
|
|
34
|
+
* @yields Next continued-fraction term of sqrt(N).
|
|
35
|
+
*/
|
|
36
|
+
static sqrt(N: number): Generator<number, void, unknown>;
|
|
37
|
+
/**
|
|
38
|
+
* Generator for continued-fraction terms of any real number via Fraction.js.
|
|
39
|
+
*
|
|
40
|
+
* @param n The real number to convert (as number, string, or bigint).
|
|
41
|
+
* @yields Next continued-fraction term of n.
|
|
42
|
+
*/
|
|
43
|
+
static fromNumber(n: Coefficient): Generator<bigint, void, unknown>;
|
|
44
|
+
/**
|
|
45
|
+
* Generator for continued-fraction terms of a rational a/b via Fraction.js.
|
|
46
|
+
*
|
|
47
|
+
* @param a Numerator, Fraction, or complete fraction string.
|
|
48
|
+
* @param b Optional denominator.
|
|
49
|
+
* @yields Next continued-fraction term of a/b.
|
|
50
|
+
*/
|
|
51
|
+
static fromFraction(a: Coefficient, b?: Coefficient): Generator<bigint, void, unknown>;
|
|
52
|
+
/**
|
|
53
|
+
* Yields a finite sequence of simple or generalized terms unchanged.
|
|
54
|
+
*
|
|
55
|
+
* @param terms Continued-fraction terms.
|
|
56
|
+
* @yields Each supplied term in order.
|
|
57
|
+
*/
|
|
58
|
+
static fromTerms<T extends ContinuedFractionTerm>(terms: Iterable<T>): Generator<T, void, unknown>;
|
|
59
|
+
/**
|
|
60
|
+
* Infinite generator of the golden ratio phi = [1; 1, 1, 1, ...].
|
|
61
|
+
*
|
|
62
|
+
* @yields Always 1.
|
|
63
|
+
*/
|
|
64
|
+
static PHI(): Generator<number, never, unknown>;
|
|
65
|
+
/**
|
|
66
|
+
* Infinite generator for Brouncker's generalized continued fraction of 4/pi:
|
|
67
|
+
* 4/pi = 1 + 1^2/(2 + 3^2/(2 + 5^2/(2 + ...)))
|
|
68
|
+
*
|
|
69
|
+
* @yields Term pair (a_n, b_n) of the generalized continued fraction.
|
|
70
|
+
* - first: a_0 = 1
|
|
71
|
+
* - then: a_n = 2, b_n = (2n-1)^2 (n >= 1)
|
|
72
|
+
*/
|
|
73
|
+
static FOUR_OVER_PI(): Generator<CFTerm, never, unknown>;
|
|
74
|
+
/**
|
|
75
|
+
* Infinite generator for a generalized continued fraction of pi:
|
|
76
|
+
* pi = 3 + 1^2/(6 + 3^2/(6 + 5^2/(6 + ...)))
|
|
77
|
+
*
|
|
78
|
+
* @yields Term pair (a_n, b_n) of the generalized continued fraction.
|
|
79
|
+
* - first: a_0 = 3
|
|
80
|
+
* - then: a_n = 6, b_n = (2n-1)^2 (n >= 1)
|
|
81
|
+
*/
|
|
82
|
+
static PI(): Generator<CFTerm, never, unknown>;
|
|
83
|
+
/**
|
|
84
|
+
* Infinite generator of e = [2; 1, 2, 1, 1, 4, 1, ...].
|
|
85
|
+
* Terms follow the pattern [2; (1, 2m, 1) for m = 1, 2, 3, ...].
|
|
86
|
+
*
|
|
87
|
+
* @yields Next continued-fraction term of e.
|
|
88
|
+
*/
|
|
89
|
+
static E(): Generator<number, never, unknown>;
|
|
90
|
+
/**
|
|
91
|
+
* Collects at most `steps` terms from a continued fraction.
|
|
92
|
+
*
|
|
93
|
+
* @param source Continued-fraction term iterator or a function returning one.
|
|
94
|
+
* @param steps Maximum number of terms to collect.
|
|
95
|
+
* @returns Collected terms in source order.
|
|
96
|
+
*/
|
|
97
|
+
static toArray<T>(source: ContinuedFractionSource<T>, steps?: number): T[];
|
|
98
|
+
/**
|
|
99
|
+
* Generates every convergent of a simple or generalized continued fraction.
|
|
100
|
+
*
|
|
101
|
+
* @param source Continued-fraction term iterator or a function returning one.
|
|
102
|
+
* @yields Exact convergents as Fraction instances.
|
|
103
|
+
*/
|
|
104
|
+
static convergents(source: ContinuedFractionSource): Generator<FractionValue, void, unknown>;
|
|
105
|
+
/**
|
|
106
|
+
* Evaluates a simple or generalized continued fraction generator.
|
|
107
|
+
* For generalized fractions terms are objects `{ a, b }`; otherwise they are coefficients.
|
|
108
|
+
*
|
|
109
|
+
* @param source Continued-fraction term iterator or a function returning one.
|
|
110
|
+
* @param steps Number of terms to evaluate.
|
|
111
|
+
* @returns Rational approximation as Fraction.
|
|
112
|
+
*/
|
|
113
|
+
static eval(source: ContinuedFractionSource, steps?: number): FractionValue;
|
|
114
|
+
}
|
|
115
|
+
export default ContinuedFraction;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { CFTerm as CFTermType, Coefficient as CoefficientType, ContinuedFraction as ContinuedFractionType, ContinuedFractionSource as ContinuedFractionSourceType, ContinuedFractionTerm as ContinuedFractionTermType } from './continuedfraction.d.mts';
|
|
2
|
+
|
|
3
|
+
declare const ContinuedFraction: typeof ContinuedFractionType & {
|
|
4
|
+
readonly default: typeof ContinuedFractionType;
|
|
5
|
+
readonly ContinuedFraction: typeof ContinuedFractionType;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
declare namespace ContinuedFraction {
|
|
9
|
+
type CFTerm = CFTermType;
|
|
10
|
+
type Coefficient = CoefficientType;
|
|
11
|
+
type ContinuedFraction = ContinuedFractionType;
|
|
12
|
+
type ContinuedFractionSource<T = ContinuedFractionTermType> = ContinuedFractionSourceType<T>;
|
|
13
|
+
type ContinuedFractionTerm = ContinuedFractionTermType;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export = ContinuedFraction;
|