Skip to content

Commit 1565710

Browse files
committed
chore lint
1 parent cca7068 commit 1565710

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+381
-254
lines changed

src/api.md

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,19 @@ This interface is augmented by `types-engine.ts` with the concrete
4949

5050
<MemberCard>
5151

52+
##### ExpressionComputeEngine.latexSyntax
53+
54+
```ts
55+
readonly latexSyntax: ILatexSyntax;
56+
```
57+
58+
The LatexSyntax instance used for LaTeX parsing/serialization.
59+
`undefined` when no LatexSyntax was provided to the constructor.
60+
61+
</MemberCard>
62+
63+
<MemberCard>
64+
5265
##### ExpressionComputeEngine.True
5366

5467
```ts
@@ -1913,7 +1926,11 @@ and functions.
19131926
toMathJson(options?): MathJsonExpression
19141927
```
19151928
1916-
Serialize to a MathJSON expression with specified options
1929+
Serialize to a MathJSON expression with specified options.
1930+
1931+
Use `{ fractionalDigits: 'auto' }` to round arbitrary-precision
1932+
numbers to `ce.precision` significant digits. The default
1933+
(`'max'`) emits all available digits with no rounding.
19171934
19181935
####### options?
19191936
@@ -1943,6 +1960,12 @@ For more control over the serialization, use `expr.toMathJson()`.
19431960
19441961
Note that lazy collections are *not* eagerly evaluated.
19451962
1963+
For arbitrary-precision numbers, the full raw `BigDecimal` value is
1964+
emitted with no rounding (same as `toJSON()`). This preserves data
1965+
fidelity for round-tripping but may include trailing digits beyond
1966+
`ce.precision` that are not meaningful. Use
1967+
`toMathJson({ fractionalDigits: 'auto' })` for rounded output.
1968+
19461969
:::info[Note]
19471970
Applicable to canonical and non-canonical expressions.
19481971
:::
@@ -1962,6 +1985,10 @@ Return a LaTeX representation of this expression.
19621985
This is a convenience getter that delegates to the standalone
19631986
`serialize()` function from the `latex-syntax` module.
19641987
1988+
Numeric values are rounded to `ce.precision` significant digits.
1989+
Noise digits from precision-bounded operations (division,
1990+
transcendentals) are not displayed.
1991+
19651992
</MemberCard>
19661993
19671994
<MemberCard>
@@ -1975,6 +2002,8 @@ toLatex(options?): string
19752002
Return a LaTeX representation of this expression with custom
19762003
serialization options.
19772004
2005+
Numeric values are rounded to `ce.precision` significant digits.
2006+
19782007
####### options?
19792008
19802009
`Record`\<`string`, `any`\>
@@ -3440,6 +3469,12 @@ Note that lazy collections are eagerly evaluated.
34403469
34413470
Used when coercing a `Expression` to a `String`.
34423471
3472+
For arbitrary-precision numbers (`BigNumericValue`), the output is
3473+
rounded to `BigDecimal.precision` significant digits. Digits beyond the
3474+
working precision are noise from precision-bounded operations (division,
3475+
transcendentals) and are not displayed. Machine-precision numbers use
3476+
their native `Number.toString()`.
3477+
34433478
</MemberCard>
34443479
34453480
<MemberCard>
@@ -3458,6 +3493,12 @@ Based on `Object.toJSON()`.
34583493
34593494
Note that lazy collections are *not* eagerly evaluated.
34603495
3496+
The output preserves the full raw `BigDecimal` value with no rounding,
3497+
ensuring lossless round-tripping via `ce.box(expr.json)`. Digits beyond
3498+
`ce.precision` may be present but are not guaranteed to be accurate.
3499+
Use `toMathJson({ fractionalDigits: 'auto' })` for precision-rounded
3500+
MathJSON output.
3501+
34613502
</MemberCard>
34623503
34633504
<MemberCard>
@@ -8404,6 +8445,47 @@ type SymbolTable = {
84048445
84058446
</MemberCard>
84068447
8448+
### ILatexSyntax
8449+
8450+
Minimal interface for a LaTeX parser/serializer.
8451+
Structurally compatible with `LatexSyntax` without importing it.
8452+
8453+
<MemberCard>
8454+
8455+
##### ILatexSyntax.parse()
8456+
8457+
```ts
8458+
parse(latex, options?): MathJsonExpression
8459+
```
8460+
8461+
####### latex
8462+
8463+
`string`
8464+
8465+
####### options?
8466+
8467+
`Partial`\<[`ParseLatexOptions`](#parselatexoptions)\>
8468+
8469+
</MemberCard>
8470+
8471+
<MemberCard>
8472+
8473+
##### ILatexSyntax.serialize()
8474+
8475+
```ts
8476+
serialize(expr, options?): string
8477+
```
8478+
8479+
####### expr
8480+
8481+
[`MathJsonExpression`](#mathjsonexpression)
8482+
8483+
####### options?
8484+
8485+
`Record`\<`string`, `unknown`\>
8486+
8487+
</MemberCard>
8488+
84078489
<MemberCard>
84088490
84098491
### RuleStep

src/big-decimal/transcendentals.ts

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,18 @@
66
*/
77

88
import { BigDecimal, fromRaw } from './big-decimal';
9-
import { bigintAbs, fpmul, fpdiv, fpsqrt, fpexp, fpln, fpsincos, fpatan, bigintDigits, pow10 } from './utils';
9+
import {
10+
bigintAbs,
11+
fpmul,
12+
fpdiv,
13+
fpsqrt,
14+
fpexp,
15+
fpln,
16+
fpsincos,
17+
fpatan,
18+
bigintDigits,
19+
pow10,
20+
} from './utils';
1021

1122
// ---------- Declaration merging ----------
1223

@@ -71,10 +82,7 @@ declare module './big-decimal' {
7182
* `precision` is the number of significant decimal digits in the
7283
* fixed-point representation.
7384
*/
74-
function toFixedPoint(
75-
x: BigDecimal,
76-
precision: number
77-
): [bigint, bigint] {
85+
function toFixedPoint(x: BigDecimal, precision: number): [bigint, bigint] {
7886
const scale = pow10(precision);
7987
// value = significand * 10^exponent
8088
// fixed-point = value * scale = significand * 10^(exponent + precision)
@@ -339,10 +347,11 @@ BigDecimal.prototype.log = function (base: BigDecimal | number): BigDecimal {
339347
return x.exp();
340348
};
341349

342-
(BigDecimal as unknown as { ln: (x: BigDecimal) => BigDecimal }).ln =
343-
function (x: BigDecimal): BigDecimal {
344-
return x.ln();
345-
};
350+
(BigDecimal as unknown as { ln: (x: BigDecimal) => BigDecimal }).ln = function (
351+
x: BigDecimal
352+
): BigDecimal {
353+
return x.ln();
354+
};
346355

347356
(BigDecimal as unknown as { log10: (x: BigDecimal) => BigDecimal }).log10 =
348357
function (x: BigDecimal): BigDecimal {
@@ -398,7 +407,9 @@ BigDecimal.prototype.tan = function (): BigDecimal {
398407
// tan = sin / cos
399408
if (cosFp === 0n) {
400409
// cos = 0 means we're at π/2 + nπ → tan is ±Infinity
401-
return sinFp > 0n ? BigDecimal.POSITIVE_INFINITY : BigDecimal.NEGATIVE_INFINITY;
410+
return sinFp > 0n
411+
? BigDecimal.POSITIVE_INFINITY
412+
: BigDecimal.NEGATIVE_INFINITY;
402413
}
403414

404415
// Fixed-point division: (sinFp * scale) / cosFp

src/big-decimal/utils.ts

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@ const _pow10Cache: Map<number, bigint> = new Map();
1616
export function pow10(n: number): bigint {
1717
if (n <= 100) {
1818
let v = _pow10Cache.get(n);
19-
if (v === undefined) { v = 10n ** BigInt(n); _pow10Cache.set(n, v); }
19+
if (v === undefined) {
20+
v = 10n ** BigInt(n);
21+
_pow10Cache.set(n, v);
22+
}
2023
return v;
2124
}
2225
return 10n ** BigInt(n);
@@ -152,7 +155,10 @@ export function bigintDigits(n: bigint): number {
152155
while (tmp >> BigInt(high) > 0n) high *= 2;
153156
// Binary search within [0, high]
154157
for (let shift = high >> 1; shift >= 1; shift >>= 1) {
155-
if (tmp >> BigInt(shift) > 0n) { bits += shift; tmp >>= BigInt(shift); }
158+
if (tmp >> BigInt(shift) > 0n) {
159+
bits += shift;
160+
tmp >>= BigInt(shift);
161+
}
156162
}
157163
bits += 1;
158164
const approx = Math.ceil(bits * 0.30102999566398);
@@ -193,14 +199,14 @@ export function fpexp(x: bigint, scale: bigint): bigint {
193199
sum += term;
194200

195201
for (let n = 2; ; n++) {
196-
term = term * r / (BigInt(n) * scale);
202+
term = (term * r) / (BigInt(n) * scale);
197203
if (bigintAbs(term) === 0n) break;
198204
sum += term;
199205
}
200206

201207
// Squaring phase: exp(x/scale) = exp(r/scale)^(2^k)
202208
for (let i = 0; i < k; i++) {
203-
sum = sum * sum / scale;
209+
sum = (sum * sum) / scale;
204210
}
205211

206212
return sum;
@@ -229,7 +235,12 @@ export function fpln(x: bigint, scale: bigint): bigint {
229235
let target = x; // the value we compute ln of (may be reduced)
230236
let k = 0; // number of sqrt halvings applied
231237

232-
if (Number.isFinite(xNum) && Number.isFinite(scaleNum) && xNum > 0 && scaleNum > 0) {
238+
if (
239+
Number.isFinite(xNum) &&
240+
Number.isFinite(scaleNum) &&
241+
xNum > 0 &&
242+
scaleNum > 0
243+
) {
233244
const ratio = xNum / scaleNum;
234245
if (Number.isFinite(ratio) && ratio > 0) {
235246
const approx = Math.log(ratio);
@@ -288,8 +299,13 @@ export function fpln(x: bigint, scale: bigint): bigint {
288299
const absDelta = bigintAbs(yn - y);
289300
if (absDelta <= 1n) break;
290301
// Detect limit cycle: both deltas are small and convergence stalled
291-
if (absDelta < 100000n && prevAbsDelta > 0n && prevAbsDelta < 100000n
292-
&& absDelta * 4n >= prevAbsDelta) break;
302+
if (
303+
absDelta < 100000n &&
304+
prevAbsDelta > 0n &&
305+
prevAbsDelta < 100000n &&
306+
absDelta * 4n >= prevAbsDelta
307+
)
308+
break;
293309
prevAbsDelta = absDelta;
294310
y = yn;
295311
}
@@ -341,7 +357,8 @@ export const PI_DIGITS =
341357
let _fppiCache: { scale: bigint; value: bigint } | null = null;
342358

343359
function fppi(scale: bigint): bigint {
344-
if (_fppiCache !== null && _fppiCache.scale === scale) return _fppiCache.value;
360+
if (_fppiCache !== null && _fppiCache.scale === scale)
361+
return _fppiCache.value;
345362

346363
// Compute PI * scale using the shared PI_DIGITS constant.
347364
// scale = 10^p, so we need ~p+10 digits of PI.
@@ -475,10 +492,10 @@ export function fpsincos(x: bigint, scale: bigint): [bigint, bigint] {
475492
for (let n = 2; ; n += 2) {
476493
// cos term: cosTerm = cosTerm * (-r²) / (n*(n-1)*scale²)
477494
// But we compute sign explicitly
478-
cosTerm = cosTerm * r2 / (BigInt(n) * BigInt(n - 1) * scale2);
495+
cosTerm = (cosTerm * r2) / (BigInt(n) * BigInt(n - 1) * scale2);
479496
if (cosTerm === 0n) {
480497
// Also check sin at next step
481-
sinTerm = sinTerm * r2 / (BigInt(n + 1) * BigInt(n) * scale2);
498+
sinTerm = (sinTerm * r2) / (BigInt(n + 1) * BigInt(n) * scale2);
482499
if (sinTerm !== 0n) {
483500
if (n % 4 === 2) {
484501
cosVal -= cosTerm;
@@ -492,7 +509,7 @@ export function fpsincos(x: bigint, scale: bigint): [bigint, bigint] {
492509
}
493510

494511
// sin term at n+1: sinTerm = sinTerm * r² / ((n+1)*n*scale²)
495-
sinTerm = sinTerm * r2 / (BigInt(n + 1) * BigInt(n) * scale2);
512+
sinTerm = (sinTerm * r2) / (BigInt(n + 1) * BigInt(n) * scale2);
496513

497514
if (n % 4 === 2) {
498515
// n=2: subtract for cos (term 2: -r²/2!), subtract for sin (term 3: -r³/3!)
@@ -511,8 +528,8 @@ export function fpsincos(x: bigint, scale: bigint): [bigint, bigint] {
511528
// sin(2θ) = 2·sin(θ)·cos(θ)
512529
// cos(2θ) = 2·cos²(θ) - 1
513530
for (let i = 0; i < k; i++) {
514-
const newSin = 2n * sinVal * cosVal / scale;
515-
const newCos = 2n * cosVal * cosVal / scale - scale;
531+
const newSin = (2n * sinVal * cosVal) / scale;
532+
const newCos = (2n * cosVal * cosVal) / scale - scale;
516533
sinVal = newSin;
517534
cosVal = newCos;
518535
}
@@ -549,13 +566,13 @@ export function fpatan(x: bigint, scale: bigint): bigint {
549566
// If x/scale > 1, use atan(x/scale) = π/2 - atan(scale/x)
550567
// In fixed-point: atan(x, scale) = halfPi - atan(scale² / x, scale)
551568
if (x > scale) {
552-
const reciprocal = scale * scale / x; // scale²/x represents scale/x in fp
569+
const reciprocal = (scale * scale) / x; // scale²/x represents scale/x in fp
553570
return halfPi - fpatan(reciprocal, scale);
554571
}
555572

556573
// Halving: if x > 0.4 * scale, use atan(x) = 2*atan(x / (1 + sqrt(1 + x²)))
557574
// In fixed-point: threshold = 4*scale/10
558-
const threshold = 4n * scale / 10n;
575+
const threshold = (4n * scale) / 10n;
559576
let halvings = 0;
560577
let r = x;
561578

@@ -568,7 +585,7 @@ export function fpatan(x: bigint, scale: bigint): bigint {
568585
const r2 = r * r;
569586
const val = (scale * scale + r2) / scale;
570587
const sqrtVal = fpsqrt(val, scale); // sqrt(1 + t²) * scale
571-
r = r * scale / (scale + sqrtVal);
588+
r = (r * scale) / (scale + sqrtVal);
572589
halvings++;
573590
}
574591

@@ -581,7 +598,7 @@ export function fpatan(x: bigint, scale: bigint): bigint {
581598
const scale2 = scale * scale; // hoisted: saves one bigint multiply per term
582599

583600
for (let n = 3; ; n += 2) {
584-
term = term * r2 / scale2;
601+
term = (term * r2) / scale2;
585602
if (term === 0n) break;
586603
// Late division by n: the per-term truncation error is < 1 ULP each,
587604
// so total error is bounded by ~nTerms/2 ULP — well within the 15 guard digits.

src/common/one-of.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
44
type MergeTypes<TypesArray extends any[], Res = {}> = TypesArray extends [
55
infer Head,
6-
...infer Rem
6+
...infer Rem,
77
]
88
? MergeTypes<Rem, Res & Head>
99
: Res;
@@ -12,7 +12,7 @@ type MergeTypes<TypesArray extends any[], Res = {}> = TypesArray extends [
1212
export type OneOf<
1313
TypesArray extends any[],
1414
Res = never,
15-
AllProperties = MergeTypes<TypesArray>
15+
AllProperties = MergeTypes<TypesArray>,
1616
> = TypesArray extends [infer Head, ...infer Rem]
1717
? OneOf<Rem, Res | OnlyFirst<Head, AllProperties>, AllProperties>
1818
: Res;

src/common/type/parse.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ class TypeParser {
265265
required: NamedElement[],
266266
optional: NamedElement[],
267267
variadic: NamedElement | undefined,
268-
variadicMin: 0 | 1 | undefined
268+
variadicMin: 0 | 1 | undefined,
269269
] {
270270
const reqArgs: NamedElement[] = [];
271271
const optArgs: NamedElement[] = [];

src/compute-engine/boxed-expression/arithmetic-add.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,6 @@ function nvSum(
444444
ce: ComputeEngine,
445445
numericValues: NumericValue[]
446446
): NumericValue[] {
447-
const makeExact = (x) => new ExactNumericValue(x, factory);
448447
const factory =
449448
ce.precision > MACHINE_PRECISION
450449
? (x) => new BigNumericValue(x)

src/compute-engine/boxed-expression/ascii-math.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ const OPERATORS: Record<
9292
string,
9393
[
9494
string | ((x: Expression, AsciiMathSerializer) => string),
95-
precedence: number
95+
precedence: number,
9696
]
9797
> = {
9898
Add: [

0 commit comments

Comments
 (0)