continuedfraction.js 0.0.2 → 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 +130 -29
- 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 +31 -30
- package/continuedfraction.d.mts +0 -69
- package/continuedfraction.d.ts +0 -62
- 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.
|
|
47
55
|
|
|
48
|
-
|
|
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
|
+
```
|
|
69
|
+
|
|
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
|
|
61
106
|
```
|
|
62
107
|
|
|
63
|
-
|
|
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`.
|
|
64
113
|
|
|
65
114
|
```javascript
|
|
66
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]
|
|
141
|
+
```
|
|
142
|
+
|
|
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.
|
|
148
|
+
|
|
149
|
+
```javascript
|
|
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,7 +169,7 @@ 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, …
|
|
78
|
-
|
|
172
|
+
```
|
|
79
173
|
|
|
80
174
|
```javascript
|
|
81
175
|
// 2) Continued‑fraction of a decimal
|
|
@@ -84,31 +178,31 @@ for (let piCf of ContinuedFraction.fromNumber(Math.PI)) {
|
|
|
84
178
|
console.log(piCf);
|
|
85
179
|
if (cnt++ >= 10) break;
|
|
86
180
|
}
|
|
87
|
-
|
|
181
|
+
```
|
|
88
182
|
|
|
89
183
|
```javascript
|
|
90
184
|
// 3) Golden ratio φ terms
|
|
91
185
|
const phiGen = ContinuedFraction.PHI();
|
|
92
186
|
console.log(phiGen.next().value); // 1, and forever 1…
|
|
93
|
-
|
|
187
|
+
```
|
|
94
188
|
|
|
95
189
|
```javascript
|
|
96
190
|
// 4) Evaluate the first 10 terms of e’s CF to a Fraction
|
|
97
191
|
const approxE = ContinuedFraction.eval(ContinuedFraction.E, 10);
|
|
98
|
-
console.log(approxE.
|
|
99
|
-
|
|
192
|
+
console.log(approxE.toFraction()); // "1457/536"
|
|
193
|
+
```
|
|
100
194
|
|
|
101
195
|
```javascript
|
|
102
196
|
// 5) Generalized CF for π, 4/π
|
|
103
197
|
const genPi = ContinuedFraction.PI();
|
|
104
198
|
console.log(genPi.next().value); // { a: 3, b: 0 }
|
|
105
199
|
console.log(genPi.next().value); // { a: 6, b: 1 }
|
|
106
|
-
|
|
200
|
+
```
|
|
107
201
|
|
|
108
202
|
```javascript
|
|
109
203
|
// 6) Continued‑fraction from two integers
|
|
110
204
|
const halfCf = ContinuedFraction.fromFraction(1, 2);
|
|
111
|
-
console.log([...halfCf]); // [
|
|
205
|
+
console.log([...halfCf]); // [0n, 2n]
|
|
112
206
|
```
|
|
113
207
|
|
|
114
208
|
### Methods
|
|
@@ -116,28 +210,35 @@ console.log([...halfCf]); // [0, 2]
|
|
|
116
210
|
| Method | Signature | Description |
|
|
117
211
|
| ------------------------ | ----------------------------------------------------------------- | ----------------------------------------------------------------------- |
|
|
118
212
|
| `sqrt(N: number)` | `Generator<number>` | Simple CF terms of √N |
|
|
119
|
-
| `fromNumber(n)` | `Generator<
|
|
120
|
-
| `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 |
|
|
121
216
|
| `PHI()` | `Generator<number>` | Infinite 1’s for the golden ratio |
|
|
122
217
|
| `FOUR_OVER_PI()` | `Generator<CFTerm>` | Generalized CF terms for 4/π |
|
|
123
218
|
| `PI()` | `Generator<CFTerm>` | Generalized CF terms for π |
|
|
124
219
|
| `E()` | `Generator<number>` | CF expansion of e |
|
|
125
|
-
| `
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
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` |
|
|
130
223
|
|
|
131
224
|
## Building the library
|
|
132
225
|
|
|
133
|
-
|
|
226
|
+
The source is strict TypeScript. The build emits CommonJS, ESM, a standalone browser bundle, source maps, and format-specific declarations.
|
|
134
227
|
|
|
135
|
-
|
|
228
|
+
After cloning the Git repository, run:
|
|
229
|
+
|
|
230
|
+
```bash
|
|
136
231
|
npm install
|
|
137
232
|
npm run build
|
|
138
233
|
```
|
|
139
234
|
|
|
235
|
+
Run all runtime and type-level tests with:
|
|
236
|
+
|
|
237
|
+
```bash
|
|
238
|
+
npm test
|
|
239
|
+
```
|
|
240
|
+
|
|
140
241
|
## Copyright and Licensing
|
|
141
242
|
|
|
142
|
-
Copyright (c)
|
|
243
|
+
Copyright (c) 2026, [Robert Eisele](https://raw.org/)
|
|
143
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;
|