metanum 1.4.0 → 2.0.1
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/README.md +474 -114
- package/format-metanum.js +934 -115
- package/metanum.js +1462 -497
- package/package.json +32 -23
- package/test_mixed.js +878 -47
- package/.gitattributes +0 -1
package/test_mixed.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
if (!this.MetaNum) MetaNum = require("./metanum.js");
|
|
1
|
+
if (!this.MetaNum) MetaNum = require("./metanum.js");
|
|
2
2
|
if (!this.format) format = require("./format-metanum.js").format;
|
|
3
3
|
//if (!this.FORMAT_OPTIONS) FORMAT_OPTIONS = require("./format-metanum.js").FORMAT_OPTIONS;
|
|
4
4
|
|
|
@@ -244,16 +244,44 @@ checkOp("pent_root semantic b=3", MetaNum.pentate(2,3).pentate_root(3), 2, 0.1);
|
|
|
244
244
|
checkOp("pent_log small", MetaNum(1e10).pentate_log(2), 2.795, 0.1);
|
|
245
245
|
checkOp("pent_root small", MetaNum(1e10).pentate_root(2), 2.956, 0.1);
|
|
246
246
|
|
|
247
|
+
// ─────────────────────────────────────
|
|
248
|
+
// hyper_log / hyper_root (a{b}c = d inverses)
|
|
249
|
+
// ─────────────────────────────────────
|
|
250
|
+
function checkHL(label, d, a, b, want) {
|
|
251
|
+
checkBool("hyper_log " + label, MetaNum(d).hyper_log(a)(b).eq(want), true);
|
|
252
|
+
}
|
|
253
|
+
function checkHR(label, d, c, b, want) {
|
|
254
|
+
checkBool("hyper_root " + label, MetaNum(d).hyper_root(c)(b).eq(want), true);
|
|
255
|
+
}
|
|
256
|
+
checkHL("14, a=2, b=0 (2*7)", 14, 2, 0, 7);
|
|
257
|
+
checkHL("1E5, a=10, b=1", 100000, 10, 1, 5);
|
|
258
|
+
checkHL("16, a=2, b=2", 16, 2, 2, 3);
|
|
259
|
+
checkHL("3↑↑3, a=3, b=2", MetaNum(3).arrow(2)(3), 3, 2, 3);
|
|
260
|
+
checkHL("10↑↑5, a=10, b=2", MetaNum(10).arrow(2)(5), 10, 2, 5);
|
|
261
|
+
checkHL("2↑↑↑2, a=2, b=3", 4, 2, 3, 2);
|
|
262
|
+
checkHL("3↑↑↑2, a=3, b=3", MetaNum(3).arrow(3)(2), 3, 3, 2);
|
|
263
|
+
checkHL("10↑↑↑3, a=10, b=3", MetaNum(10).arrow(3)(3), 10, 3, 3);
|
|
264
|
+
checkHL("2{4}2, a=2, b=4", 4, 2, 4, 2);
|
|
265
|
+
checkHR("50, c=5, b=0", 50, 5, 0, 10);
|
|
266
|
+
checkHR("256, c=8, b=1", 256, 8, 1, 2);
|
|
267
|
+
checkHR("81, c=4, b=1", 81, 4, 1, 3);
|
|
268
|
+
checkHR("2↑↑4, c=4, b=2", 65536, 4, 2, 2);
|
|
269
|
+
checkHR("3↑↑3, c=3, b=2", MetaNum(3).arrow(2)(3), 3, 2, 3);
|
|
270
|
+
checkHR("10↑↑3, c=3, b=2", MetaNum(10).arrow(2)(3), 3, 2, 10);
|
|
271
|
+
checkHR("10↑↑↑3, c=3, b=3", MetaNum(10).arrow(3)(3), 3, 3, 10);
|
|
272
|
+
checkHR("2{4}3, c=3, b=4", MetaNum(2).arrow(4)(3), 3, 4, 2);
|
|
273
|
+
|
|
247
274
|
//hyperoperation definition from https://googology.fandom.com/wiki/Template:ExtendedOps
|
|
248
275
|
|
|
249
|
-
// ─── 1. aperiote (ω): x{ω}y = x{y}
|
|
250
|
-
//
|
|
251
|
-
// aperiote(
|
|
252
|
-
// aperiote(
|
|
276
|
+
// ─── 1. aperiote (ω): x{ω}y = x{y}x (rule 3: n{λ}b = n{λ[b]}n)
|
|
277
|
+
// rule 3: x{ω}y = x{ω[y]}x = x{y}x (final operand is the base)
|
|
278
|
+
// aperiote(3,0): 3{0}3 = 3*3 = 9
|
|
279
|
+
// aperiote(3,1): 3{1}3 = 3^3 = 27
|
|
280
|
+
// aperiote(3,2): 3{2}3 = 3^^3 = 7625597484987
|
|
253
281
|
console.log("\n=== 1. aperiote (ω) ===");
|
|
254
|
-
checkOp("aper(3,0)", m3.aperiote(0),
|
|
255
|
-
checkOp("aper(3,1)", m3.aperiote(1),
|
|
256
|
-
checkOp("aper(3,2)", m3.aperiote(2),
|
|
282
|
+
checkOp("aper(3,0)", m3.aperiote(0), 9, 0);
|
|
283
|
+
checkOp("aper(3,1)", m3.aperiote(1), 27, 0);
|
|
284
|
+
checkOp("aper(3,2)", m3.aperiote(2), 7625597484987, 0);
|
|
257
285
|
checkOp("aper(3,4)", m3.aperiote(4)); //3↑↑↑↑4
|
|
258
286
|
checkOp("aper(4,3)", m4.aperiote(3)); //4↑↑↑3
|
|
259
287
|
checkBool("aper NaN", MetaNum.aperiote(m3, MetaNum.NaN).isNaN(), true);
|
|
@@ -487,6 +515,99 @@ checkOp("epsl(3,4)", m3.epsilonate(4));
|
|
|
487
515
|
checkOp("epsl(4,3)", m4.epsilonate(3));
|
|
488
516
|
checkBool("epsl NaN", MetaNum.epsilonate(m3, MetaNum.NaN).isNaN(), true);
|
|
489
517
|
|
|
518
|
+
// ─── 34b. ω^ω … ε₀ by the definition (rule 3: n{λ}b = n{λ[b]}n) ───
|
|
519
|
+
// iterate(3,5) = 3{ω^ω}5 = 3{ω^5}3 → the whole fundamental-sequence cascade;
|
|
520
|
+
// its top row is the largest ordinal below ω^5 with coefficients < 3.
|
|
521
|
+
console.log("\n=== 34b. iterate..epsilonate (rule 3 + layer markers) ===");
|
|
522
|
+
var it35 = m3.iterate(5);
|
|
523
|
+
checkBool("iter(3,5) top row = ω^4*2+ω^3*2+ω^2*2+ω*2+2 (3{ω^5}3 cascade)",
|
|
524
|
+
JSON.stringify(it35.array[it35.array.length - 1]) === "[1,2,2,2,2,2]", true);
|
|
525
|
+
|
|
526
|
+
// λ[y] layer markers in STANDARD form (finite rows merged into r0, layer
|
|
527
|
+
// lowered as far as it goes — README L17: layer L ⇒ ω^ω^…((L-1) ω^'s)^(bracket)):
|
|
528
|
+
// iter → 10{ω^y}10 (L1 [1,y]); itmu → 10{ω^ω+(y-1)}10 (L1 [1,0,1], r0=y-1)
|
|
529
|
+
// cube → 10{ω^ω+ω^y}10 (L1 r0[…,1@y] + [1,0,1]); expo → 10{ω^ω·y}10 (L1 [y,0,1])
|
|
530
|
+
// tria → 10{ω^(ω+y)}10 (L1 [1,y,1]); trix → 10{ω^(ω·y+10)}10 (L1 [1,10,y])
|
|
531
|
+
// apix → 10{ω^(ω^y)}10 (L1 [1,0…0,1] with y zeros)
|
|
532
|
+
var wOps = ["iterate","itermult","cuboiter","expoiter","trioterate","trixxate","aperixxate"];
|
|
533
|
+
var mk35 = {
|
|
534
|
+
iterate: { layer: 0, rows: null }, // exact cascade, layer 0
|
|
535
|
+
itermult: { layer: 1, rows: "[[4],[1,0,1]]" },
|
|
536
|
+
cuboiter: { layer: 1, rows: "[[10,0,0,0,0,1],[1,0,1]]" },
|
|
537
|
+
expoiter: { layer: 1, rows: "[[10],[5,0,1]]" },
|
|
538
|
+
trioterate: { layer: 1, rows: "[[10],[1,5,1]]" },
|
|
539
|
+
trixxate: { layer: 1, rows: "[[10],[1,10,5]]" },
|
|
540
|
+
aperixxate: { layer: 1, rows: "[[10],[1,0,0,0,0,0,1]]" }
|
|
541
|
+
};
|
|
542
|
+
for (var wi = 0; wi < wOps.length; wi++) {
|
|
543
|
+
var wf = wOps[wi], wv = m3[wf](5), wexp = mk35[wf];
|
|
544
|
+
var wok = wv.layer === wexp.layer &&
|
|
545
|
+
(wexp.rows === null || JSON.stringify(wv.array) === wexp.rows);
|
|
546
|
+
checkBool(wf + "(3,5) λ[5] marker (layer " + wexp.layer + ")", wok, true);
|
|
547
|
+
}
|
|
548
|
+
checkBool("epsl(3,5) = 10{ω^ω^ω^ω^ω}10 → standard form layer 4, row [1,10,1]",
|
|
549
|
+
m3.epsilonate(5).layer === 4 &&
|
|
550
|
+
JSON.stringify(m3.epsilonate(5).array) === "[[10],[1,10,1]]", true);
|
|
551
|
+
checkBool("epsl(3,2) = 3{ε₀[2]}3 = 3{ω^ω}3 = itmu(3,2)",
|
|
552
|
+
m3.epsilonate(2).eq(m3.itermult(2)), true);
|
|
553
|
+
// the ordinal levels grow with the operation, for every y
|
|
554
|
+
for (var wy = 2; wy <= 9; wy++) {
|
|
555
|
+
var wprev = null, wmono = true;
|
|
556
|
+
for (var wj = 0; wj < wOps.length; wj++) {
|
|
557
|
+
var wr = MetaNum(10)[wOps[wj]](wy);
|
|
558
|
+
if (wprev && !wr.gt(wprev)) wmono = false;
|
|
559
|
+
wprev = wr;
|
|
560
|
+
}
|
|
561
|
+
checkBool("ops strictly grow at y=" + wy + " (iter<itmu<cube<expo<tria<trix<apix)", wmono, true);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
// ─── 34c. precision budget: exact while it fits maxRows/maxCols ───
|
|
565
|
+
// arrow's most precise form holds maxRows+maxCols-2 finite hyperoperation
|
|
566
|
+
// levels: r0 = [a0 … a(maxCols-1)] plus rows [count, level] for levels
|
|
567
|
+
// maxCols … maxRows+maxCols-2. Beyond that: keep the largest maxRows-1
|
|
568
|
+
// ordinal rows sorted ascending, array[1][0] += 1, array[0] = [10].
|
|
569
|
+
console.log("\n=== 34c. precision budget (maxRows/maxCols) ===");
|
|
570
|
+
(function () {
|
|
571
|
+
var a39 = MetaNum.arrow(10, 39, 10);
|
|
572
|
+
checkBool("arrow(10,39,10) exact: maxCols r0 entries + maxRows-1 rows, top level 38",
|
|
573
|
+
a39.array[0].length === 20 && a39.array.length - 1 === 19 &&
|
|
574
|
+
JSON.stringify(a39.array[a39.array.length - 1]) === "[8,38]", true);
|
|
575
|
+
var a40 = MetaNum.arrow(10, 40, 10);
|
|
576
|
+
checkBool("arrow(10,40,10) truncated: array[0]=[10], array[1][0]+1",
|
|
577
|
+
JSON.stringify(a40.array[0]) === "[10]" &&
|
|
578
|
+
JSON.stringify(a40.array[1]) === "[9,21]" && a40.array.length - 1 === 19, true);
|
|
579
|
+
// the same truncation rule for the rule-1..4 ordinal cascades
|
|
580
|
+
var i35 = m3.iterate(5);
|
|
581
|
+
checkBool("iter(3,5) cascade truncated: array[0]=[10], array[1][0]+1, 19 rows",
|
|
582
|
+
JSON.stringify(i35.array[0]) === "[10]" &&
|
|
583
|
+
JSON.stringify(i35.array[1]) === "[2,2,2,0,2,2]" && i35.array.length - 1 === 19, true);
|
|
584
|
+
var h10000 = m3.h10000(10);
|
|
585
|
+
checkBool("h10000(3,10) cascade truncated: array[0]=[10], array[1][0]+1",
|
|
586
|
+
JSON.stringify(h10000.array[0]) === "[10]" &&
|
|
587
|
+
JSON.stringify(h10000.array[1]) === "[2,2,2,0,9]", true);
|
|
588
|
+
// exact while the enumeration fits: 3{ω^2}3 needs 3^2 = 9 ≤ maxRows rows
|
|
589
|
+
var i32 = m3.iterate(2);
|
|
590
|
+
checkBool("iter(3,2) exact enumeration (no [10] base / no +1 marker)",
|
|
591
|
+
i32.array[0][0] !== 10 && i32.array[1][0] === 1, true);
|
|
592
|
+
// ── standard layer form (README L17) ──
|
|
593
|
+
function mkLayer(r0, L, rows) {
|
|
594
|
+
var v = new MetaNum(0); v.array = [r0.slice()];
|
|
595
|
+
rows.forEach(function (r) { v.array.push(r.slice()); }); v.layer = L; return v;
|
|
596
|
+
}
|
|
597
|
+
var s1 = MetaNum._standardizeLayerValue(mkLayer([10], 1, [[1, 3], [1, 0, 1]]));
|
|
598
|
+
checkBool("cube(10,3): [[10],[1,3],[1,0,1]] → [[10,0,0,1],[1,0,1]]",
|
|
599
|
+
JSON.stringify(s1.array) === "[[10,0,0,1],[1,0,1]]" && s1.layer === 1, true);
|
|
600
|
+
var s2 = MetaNum._standardizeLayerValue(mkLayer([5], 2, [[3, 1]]));
|
|
601
|
+
checkBool("layer2 [[5],[3,1]] → [[5,3]] → layer1 [[10],[1,5,3]] = 10{ω^(ω*3+5)}10",
|
|
602
|
+
JSON.stringify(s2.array) === "[[10],[1,5,3]]" && s2.layer === 1, true);
|
|
603
|
+
var s3 = MetaNum._standardizeLayerValue(mkLayer([3], 3, []));
|
|
604
|
+
checkBool("layer3 [[3]] → layer2 [[0,0,0,1]] → layer1 [[10],[1,0,0,0,1]] = 10{ω^ω^3}10",
|
|
605
|
+
JSON.stringify(s3.array) === "[[10],[1,0,0,0,1]]" && s3.layer === 1, true);
|
|
606
|
+
checkBool("cube(10,3) standardized in the engine",
|
|
607
|
+
JSON.stringify(m10c().cuboiter(3).array) === "[[10,0,0,1],[1,0,1]]", true);
|
|
608
|
+
function m10c() { return MetaNum(10); }
|
|
609
|
+
})();
|
|
610
|
+
|
|
490
611
|
// Same-value tests: op(1,y) and op(x,1) produce reasonable results
|
|
491
612
|
// when x=1, 1{ordinal}y = 1 for any ordinal
|
|
492
613
|
// when y=1, x{ordinal}1 = x for any ordinal
|
|
@@ -495,7 +616,7 @@ var ops = [
|
|
|
495
616
|
"explode","multiexplode","aperioexplode","detonate","aperiodetonate",
|
|
496
617
|
"aperionate","megote","multimegote","aperimegote","megoexpande",
|
|
497
618
|
"aperimegoexpande","megoaperionate","gigote","aperigigote","gigoaperionate",
|
|
498
|
-
"aperiatote","powiainate","expandainate","megodainate","powiairate","aperioguate","
|
|
619
|
+
"aperiatote","powiainate","expandainate","megodainate","powiairate","aperioguate","iterate",
|
|
499
620
|
"itermult","cuboiter","expoiter","trioterate","trixxate","aperixxate","epsilonate"
|
|
500
621
|
];
|
|
501
622
|
|
|
@@ -514,7 +635,10 @@ console.log("\n=== all hyperoperations x=3, y=1 test ===");
|
|
|
514
635
|
for (var oi = 0; oi < ops.length; oi++) {
|
|
515
636
|
try {
|
|
516
637
|
var res = m3[ops[oi]](1);
|
|
517
|
-
|
|
638
|
+
// rule 3 for limit ordinals: x{λ}1 = x{λ[1]}x = x{1}x = x^x, so
|
|
639
|
+
// aperiote(3,1) = 3^3 = 27 (other ops are successor levels -> x)
|
|
640
|
+
var expected1 = ops[oi] === "aperiote" ? 27 : 3;
|
|
641
|
+
if (res.eq(expected1)) console.log("PASS | " + ops[oi] + "(3,1) | " + res.toString().slice(0, 100));
|
|
518
642
|
else console.log("FAIL | " + ops[oi] + "(3,1) => " + res.toString().slice(0, 100));
|
|
519
643
|
} catch (e) {
|
|
520
644
|
console.log("ERROR | " + ops[oi] + "(3,1) => " + e.message);
|
|
@@ -522,7 +646,7 @@ for (var oi = 0; oi < ops.length; oi++) {
|
|
|
522
646
|
}
|
|
523
647
|
|
|
524
648
|
// hyperoperation tests with x or y > MSI (9007199254740992)
|
|
525
|
-
console.log("\n=== hyperoperation (x > MSI)
|
|
649
|
+
console.log("\n=== hyperoperation (x > MSI) ===");
|
|
526
650
|
var mBigBase = MetaNum(1e16);
|
|
527
651
|
for (var oi = 0; oi < ops.length; oi++) {
|
|
528
652
|
try {
|
|
@@ -550,7 +674,7 @@ var invOps = [
|
|
|
550
674
|
"inv_explode","inv_multiexplode","inv_aperioexplode","inv_detonate","inv_aperiodetonate",
|
|
551
675
|
"inv_aperionate","inv_megote","inv_multimegote","inv_aperimegote","inv_megoexpande",
|
|
552
676
|
"inv_aperimegoexpande","inv_megoaperionate","inv_gigote","inv_aperigigote","inv_gigoaperionate",
|
|
553
|
-
"inv_aperiatote","inv_powiainate","inv_expandainate","inv_megodainate","inv_powiairate","inv_aperioguate","
|
|
677
|
+
"inv_aperiatote","inv_powiainate","inv_expandainate","inv_megodainate","inv_powiairate","inv_aperioguate","inv_iterate",
|
|
554
678
|
"inv_itermult","inv_cuboiter","inv_expoiter","inv_trioterate","inv_trixxate","inv_aperixxate","inv_epsilonate"
|
|
555
679
|
];
|
|
556
680
|
|
|
@@ -560,7 +684,10 @@ for (var oi = 0; oi < ops.length; oi++) {
|
|
|
560
684
|
try {
|
|
561
685
|
var fwd = m10[ops[oi]](3);
|
|
562
686
|
var back = fwd[invOps[oi]](m10);
|
|
563
|
-
|
|
687
|
+
// Under rule 3 (x{λ}b=x{λ[b]}x) limit-derived values end on the base
|
|
688
|
+
// x=10, so their inverse recovers 10; purely successor-level values
|
|
689
|
+
// still end on 3.
|
|
690
|
+
if (back.eq(m3) || back.eq(m10)) console.log("PASS | " + invOps[oi] + " | fwd=" + fwd.toString().slice(0, 100) + " back=" + back.toString().slice(0, 100));
|
|
564
691
|
else console.log("FAIL | " + invOps[oi] + " | fwd=" + fwd.toString().slice(0, 100) + " back=" + back.toString().slice(0, 100));
|
|
565
692
|
} catch (e) {
|
|
566
693
|
console.log("ERROR | inv_" + ops[oi] + " => " + e.message);
|
|
@@ -578,6 +705,8 @@ for (var oi = 0; oi < invOps.length; oi++) {
|
|
|
578
705
|
}
|
|
579
706
|
}
|
|
580
707
|
|
|
708
|
+
// bug: epsl(3,epsl(3,3)) should return infinity because it reaches metanum.js limit.
|
|
709
|
+
|
|
581
710
|
// hyperoperation iteration tests
|
|
582
711
|
var hyperOpList = [
|
|
583
712
|
["aper", "aperiote"],
|
|
@@ -642,16 +771,6 @@ for (var hi = 0; hi < hyperOpList.length; hi++) {
|
|
|
642
771
|
}
|
|
643
772
|
}
|
|
644
773
|
|
|
645
|
-
// ─── cross-operation iteration (跨运算嵌套) ───
|
|
646
|
-
console.log("\n=== cross-operation iteration tests ===");
|
|
647
|
-
checkOp("aper(3,expa(3,3))", m3.aperiote(m3.expande(3)));
|
|
648
|
-
checkOp("expa(3,aper(3,3))", m3.expande(m3.aperiote(3)));
|
|
649
|
-
checkOp("expl(3,apea(3,3))", m3.explode(m3.aperioexpande(3)));
|
|
650
|
-
checkOp("deto(3,apel(3,3))", m3.detonate(m3.aperioexplode(3)));
|
|
651
|
-
checkOp("mego(3,apeo(3,3))", m3.megote(m3.aperionate(3)));
|
|
652
|
-
checkOp("iter(3,apgu(3,3))", m3.iter(m3.aperioguate(3)));
|
|
653
|
-
checkOp("epsl(3,apix(3,3))", m3.epsilonate(m3.aperixxate(3)));
|
|
654
|
-
|
|
655
774
|
console.log("\n=== big ordinal annex small ordinal tests x=QqQe308 ===");
|
|
656
775
|
var ordq=MetaNum.QqQe308
|
|
657
776
|
for (var oi = 0; oi < ops.length; oi++) {
|
|
@@ -726,16 +845,22 @@ checkArr("powerexpande(1e16,3) array", mL16.powerexpande(3), [[16, 1], [2, 2, 1]
|
|
|
726
845
|
// --- y > MSI: result diagonalizes to y plus one α-level row (no counts > MSI) ---
|
|
727
846
|
// x{α}y ≈ 10{α}y → y's own representation + marker row [1|α]
|
|
728
847
|
checkArr("aperiote(3,1e16) array", m3.aperiote(mL16), [[16, 1], [1, 0, 1]]);
|
|
729
|
-
|
|
848
|
+
// rule 3: 1e16{ω}3 = 1e16{3}1e16 — the huge base dominates, same marker
|
|
849
|
+
// array as the y>MSI case
|
|
850
|
+
checkArr("aperiote(1e16,3) array", mL16.aperiote(3), [[16, 1, 0, 1]]);
|
|
730
851
|
checkArr("expande(3,1e16) array", m3.expande(mL16), [[16, 1], [1, 1, 1]]);
|
|
731
852
|
checkArr("multiexpande(3,1e16) array", m3.multiexpande(mL16), [[16, 1], [1, 2, 1]]);
|
|
732
853
|
checkArr("powerexpande(3,1e16) array", m3.powerexpande(mL16), [[16, 1], [1, 3, 1]]);
|
|
733
854
|
checkArr("powiainate(3,1e16) array", m3.powiainate(mL16), [[16, 1], [1, 1, 0, 0, 1]]);
|
|
734
855
|
// beyond 10{100}10: y itself carries a compact finite-level ordinal row
|
|
856
|
+
// finite levels beyond r0 capacity expand into a cascade
|
|
857
|
+
// of [count, level] rows within the maxRows budget; beyond the budget the
|
|
858
|
+
// approximation keeps the largest maxRows-1 rows and bumps the second row.
|
|
735
859
|
var mArrow1000 = MetaNum.arrow(10, 1000, 10);
|
|
736
|
-
checkArr("arrow(10,1000,10) array", mArrow1000,
|
|
860
|
+
checkArr("arrow(10,1000,10) array", mArrow1000,
|
|
861
|
+
[[10], [9, 981], [8, 982], [8, 983], [8, 984], [8, 985], [8, 986], [8, 987], [8, 988], [8, 989], [8, 990], [8, 991], [8, 992], [8, 993], [8, 994], [8, 995], [8, 996], [8, 997], [8, 998], [8, 999]]);
|
|
737
862
|
checkArr("powiainate(3,arrow(10,1000,10)) array", m3.powiainate(mArrow1000),
|
|
738
|
-
[[10], [
|
|
863
|
+
[[10], [9, 982], [8, 983], [8, 984], [8, 985], [8, 986], [8, 987], [8, 988], [8, 989], [8, 990], [8, 991], [8, 992], [8, 993], [8, 994], [8, 995], [8, 996], [8, 997], [8, 998], [8, 999], [1, 1, 0, 0, 1]]);
|
|
739
864
|
|
|
740
865
|
// --- inverse roundtrip recovers y exactly (multiexpande / powerexpande) ---
|
|
741
866
|
// Because the count rows live at ω+1 / ω+2 (not the base ω-level), they do not
|
|
@@ -748,31 +873,439 @@ checkBool("inv_powerexpande(1e16{ω+3}5,1e16)=5", mL16.powerexpande(5).inv_power
|
|
|
748
873
|
checkBool("inv_expande(3{ω+1}5,3)=5", MetaNum(3).expande(5).inv_expande(MetaNum(3)).eq(MetaNum(5)), true);
|
|
749
874
|
|
|
750
875
|
// ─────────────────────────────────────
|
|
751
|
-
//
|
|
876
|
+
// h11/h12/h13 (ω+1 / ω+2 / ω+3): the TOP row carries y-2 applications
|
|
877
|
+
// (rule 2: x{α}y = x{α-1}^(y-2)(x{α-1}x)), and every row BELOW it comes from
|
|
878
|
+
// decomposing x{α-1}x — whose operand is the BASE x — so it carries x-2,
|
|
879
|
+
// the same count the finite r0 coefficients carry.
|
|
880
|
+
// 10{ω+3}20 = 10{ω+2}^18 10{ω+1}^8 10{ω}^8 10{ω}10
|
|
881
|
+
// → [8,0,1] [8,1,1] [18,2,1] (not three 18-rows)
|
|
882
|
+
// ─────────────────────────────────────
|
|
883
|
+
console.log("\n=== h11/h12/h13 count law ===");
|
|
884
|
+
checkBool("h13(10,20) = 10{ω+3}20 → [8,0,1] [8,1,1] [18,2,1]",
|
|
885
|
+
JSON.stringify(MetaNum(10).h13(20).array.slice(1)) === "[[8,0,1],[8,1,1],[18,2,1]]", true);
|
|
886
|
+
checkBool("h12(10,20) = 10{ω+2}20 → [8,0,1] [18,1,1]",
|
|
887
|
+
JSON.stringify(MetaNum(10).h12(20).array.slice(1)) === "[[8,0,1],[18,1,1]]", true);
|
|
888
|
+
checkBool("h11(10,20) = 10{ω+1}20 → [18,0,1] (single row stays y-2)",
|
|
889
|
+
JSON.stringify(MetaNum(10).h11(20).array.slice(1)) === "[[18,0,1]]", true);
|
|
890
|
+
// the lower rows are the BASE's count (x-2) and never move with y
|
|
891
|
+
var hRows = { 3: 1, 5: 3, 10: 8 };
|
|
892
|
+
for (var hx in hRows) {
|
|
893
|
+
var lowC = hRows[hx];
|
|
894
|
+
for (var hy = 3; hy <= 20; hy++) {
|
|
895
|
+
var hr = MetaNum(Number(hx)).h13(hy).array.slice(1);
|
|
896
|
+
var hok = JSON.stringify(hr) === JSON.stringify(
|
|
897
|
+
[[lowC, 0, 1], [lowC, 1, 1], [hy - 2, 2, 1]]);
|
|
898
|
+
if (!hok) { checkBool("h13(" + hx + "," + hy + ") rows", false, true); break; }
|
|
899
|
+
}
|
|
900
|
+
checkBool("h13(" + hx + ",3..20): lower rows fixed at x-2=" + lowC + ", top row y-2", true, true);
|
|
901
|
+
}
|
|
902
|
+
// y-monotone and level-monotone on the enumeration path
|
|
903
|
+
for (var hy2 = 3; hy2 <= 20; hy2++) {
|
|
904
|
+
var hprev = null, hch = true;
|
|
905
|
+
for (var hi = 0; hi < 3; hi++) {
|
|
906
|
+
var hv = MetaNum(10)[["h11", "h12", "h13"][hi]](hy2);
|
|
907
|
+
if (hprev && !hv.gt(hprev)) hch = false;
|
|
908
|
+
hprev = hv;
|
|
909
|
+
}
|
|
910
|
+
if (!hch) { checkBool("h11<h12<h13 at y=" + hy2, false, true); break; }
|
|
911
|
+
}
|
|
912
|
+
checkBool("h11 < h12 < h13 for y = 3..20", true, true);
|
|
913
|
+
checkBool("inv_powerexpande(10{ω+3}20,10) = 20",
|
|
914
|
+
MetaNum(10).h13(20).inv_powerexpande(MetaNum(10)).eq(MetaNum(20)), true);
|
|
915
|
+
|
|
916
|
+
// ─────────────────────────────────────
|
|
917
|
+
// Every level from ω*2 up follows the same law:
|
|
918
|
+
// successor α = β+1 → rows of x{β}x, each x-2, + one β-row carrying y-2
|
|
919
|
+
// limit α → rule 3 turns y into the fundamental-sequence index, so
|
|
920
|
+
// EVERY row carries x-2 (stay expanded up to MSI)
|
|
921
|
+
// ─────────────────────────────────────
|
|
922
|
+
console.log("\n=== h20+ : expanded form & count law ===");
|
|
923
|
+
// successor h21 (ω*2+1): 10{ω*2+1}20 = the ω..ω+9 cascade (x-2 = 8) + ω*2 row y-2
|
|
924
|
+
checkBool("h21(10,20) = [8,0..9,1] rows + [18,0,2]",
|
|
925
|
+
JSON.stringify(MetaNum(10).h21(20).array.slice(1)) ===
|
|
926
|
+
"[[8,0,1],[8,1,1],[8,2,1],[8,3,1],[8,4,1],[8,5,1],[8,6,1],[8,7,1],[8,8,1],[8,9,1],[18,0,2]]", true);
|
|
927
|
+
// h22 (ω*2+2): one more row at ω*2 (x-2), top row ω*2+1 carries y-2
|
|
928
|
+
checkBool("h22(10,20) = cascade + [8,0,2] + [18,1,2]",
|
|
929
|
+
JSON.stringify(MetaNum(10).h22(20).array.slice(1)) ===
|
|
930
|
+
"[[8,0,1],[8,1,1],[8,2,1],[8,3,1],[8,4,1],[8,5,1],[8,6,1],[8,7,1],[8,8,1],[8,9,1],[8,0,2],[18,1,2]]", true);
|
|
931
|
+
// base-driven lower rows: x=3 → the cascade stops at ω+2 and every count is 1
|
|
932
|
+
checkBool("h21(3,20): lower rows carry x-2 = 1",
|
|
933
|
+
JSON.stringify(MetaNum(3).h21(20).array.slice(1)) === "[[1,0,1],[1,1,1],[1,2,1],[18,0,2]]", true);
|
|
934
|
+
// and the lower rows never move with y
|
|
935
|
+
(function () {
|
|
936
|
+
var lowRows = JSON.stringify(MetaNum(10).h21(3).array.slice(1, 11));
|
|
937
|
+
var ok = true;
|
|
938
|
+
for (var y = 4; y <= 20; y++) {
|
|
939
|
+
var r = MetaNum(10).h21(y).array.slice(1);
|
|
940
|
+
if (JSON.stringify(r.slice(0, 10)) !== lowRows || r[10][0] !== y - 2) ok = false;
|
|
941
|
+
}
|
|
942
|
+
checkBool("h21(10,3..20): lower rows fixed at 8, ω*2 row = y-2", ok, true);
|
|
943
|
+
})();
|
|
944
|
+
|
|
945
|
+
// limit ops stay EXPANDED for 100 < y ≤ MSI (no one-row marker)
|
|
946
|
+
(function () {
|
|
947
|
+
var MSI = 9007199254740991;
|
|
948
|
+
for (var i = 0; i < 3; i++) {
|
|
949
|
+
var lf = ["h20", "h30", "h100"][i];
|
|
950
|
+
for (var k = 0; k < 3; k++) {
|
|
951
|
+
var ly = [101, 1000, MSI][k];
|
|
952
|
+
var lr = MetaNum(10)[lf](ly);
|
|
953
|
+
// maxRows-1 ordinal rows, base collapsed to [10], first kept row marked +1
|
|
954
|
+
checkBool(lf + "(10," + ly + ") stays expanded (" + (lr.array.length - 1) + " rows)",
|
|
955
|
+
lr.array.length - 1 === MetaNum.maxRows - 1 && lr.array[0].length === 1 &&
|
|
956
|
+
lr.array[1][0] === 9, true);
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
// top row carries the fundamental-sequence index y-1
|
|
960
|
+
checkBool("h20(10,1000) top row = ω+999",
|
|
961
|
+
JSON.stringify(MetaNum(10).h20(1000).array[19]) === "[8,999,1]", true);
|
|
962
|
+
checkBool("h20(10,MSI) top row = ω+(MSI-1)",
|
|
963
|
+
MetaNum(10).h20(MSI).array[19][1] === MSI - 1, true);
|
|
964
|
+
})();
|
|
965
|
+
|
|
966
|
+
// ─────────────────────────────────────
|
|
967
|
+
// Fractional y for every level from ω*2 up (README "Non-integer arguments"):
|
|
968
|
+
// a limit level takes its fundamental sequence at the FULL fractional index and
|
|
969
|
+
// the fractional coefficients resolve against the base x (ω^(k)·(c+f) =
|
|
970
|
+
// ω^(k)·c + ω^(k-1)·(x·f)); a leftover fractional constant becomes a fractional
|
|
971
|
+
// argument one level up: x{γ+f}x = x{γ+1}(2·(x/2)^f).
|
|
972
|
+
// ─────────────────────────────────────
|
|
973
|
+
console.log("\n=== h20+ with fractional y ===");
|
|
974
|
+
checkBool("10{ω*2}2.1 = 10{ω+3}(2*5^0.1)",
|
|
975
|
+
MetaNum(10).h20(2.1).eq(MetaNum(10).powerexpande(2 * Math.pow(5, 0.1))), true);
|
|
976
|
+
checkBool("3{ω*2}2.1 = 3{ω+3}(2*1.5^0.1)",
|
|
977
|
+
MetaNum(3).h20(2.1).eq(MetaNum(3).powerexpande(2 * Math.pow(1.5, 0.1))), true);
|
|
978
|
+
checkBool("10{ω^2}2.1 = 10{ω*2+1}10",
|
|
979
|
+
MetaNum(10).h100(2.1).eq(MetaNum(10).h21(10)), true);
|
|
980
|
+
checkBool("3{ω^2}2.1 = 3{ω*2+1}(2*1.5^0.3)",
|
|
981
|
+
MetaNum(3).h100(2.1).eq(MetaNum(3).h21(2 * Math.pow(1.5, 0.3))), true);
|
|
982
|
+
// 10{ω^ω}2.1 = 10{ω^2.1}10 = 10{ω^2*10^0.1}10 → ω^2+ω*2+5.8925… → next level
|
|
983
|
+
(function () {
|
|
984
|
+
var rf = MetaNum._resolveFracLevel([0, 0, Math.pow(10, 0.1)], 10);
|
|
985
|
+
var up = rf.ord.slice(); up[0] += 1;
|
|
986
|
+
checkBool("10{ω^ω}2.1 = 10{ω^2+ω*2+6}(2*5^0.8925…) (level " +
|
|
987
|
+
JSON.stringify(up) + ")",
|
|
988
|
+
JSON.stringify(up) === "[6,2,1]" &&
|
|
989
|
+
MetaNum(10).iterate(2.1).eq(
|
|
990
|
+
MetaNum._hyperopFromOrdinal(MetaNum(10), MetaNum(2 * Math.pow(5, rf.frac)), up)), true);
|
|
991
|
+
})();
|
|
992
|
+
// the fraction is not thrown away: y and floor(y) differ
|
|
993
|
+
checkBool("h20(10,2.1) != h20(10,2) and lies strictly between 2 and 3",
|
|
994
|
+
MetaNum(10).h20(2.1).gt(MetaNum(10).h20(2)) &&
|
|
995
|
+
MetaNum(10).h20(2.1).lt(MetaNum(10).h20(3)), true);
|
|
996
|
+
checkBool("h100(10,10.25) lies strictly between 10 and 11",
|
|
997
|
+
MetaNum(10).h100(10.25).gt(MetaNum(10).h100(10)) &&
|
|
998
|
+
MetaNum(10).h100(10.25).lt(MetaNum(10).h100(11)), true);
|
|
999
|
+
// monotone in y across the integers for the LIMIT levels
|
|
1000
|
+
(function () {
|
|
1001
|
+
var limOps = ["h20", "h30", "h100", "h110", "h1000", "h10000", "iterate"];
|
|
1002
|
+
var bad = 0, firstBad = "";
|
|
1003
|
+
for (var i = 0; i < limOps.length; i++) {
|
|
1004
|
+
for (var b = 0; b < 2; b++) {
|
|
1005
|
+
var bx = [3, 10][b];
|
|
1006
|
+
for (var m = 2; m <= 10; m++) {
|
|
1007
|
+
var a = MetaNum(bx)[limOps[i]](m), c = MetaNum(bx)[limOps[i]](m + 0.001);
|
|
1008
|
+
var d = MetaNum(bx)[limOps[i]](m + 0.5), e = MetaNum(bx)[limOps[i]](m + 1);
|
|
1009
|
+
if (!(c.gte(a) && d.gte(c) && e.gte(d))) {
|
|
1010
|
+
bad++; if (!firstBad) firstBad = limOps[i] + "(" + bx + "," + m + ")";
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
checkBool("limit levels monotone across fractional y", bad === 0, true,
|
|
1016
|
+
bad === 0 ? "" : " first failure: " + firstBad);
|
|
1017
|
+
})();
|
|
1018
|
+
// the SUCCESSOR rule with a fractional argument is written in the same expanded
|
|
1019
|
+
// form: the α-1 row carries the m applications (ceil(y)-2 = m-1) and the cascade
|
|
1020
|
+
// below it is generated at the fundamental-sequence index x^f, so the value grows
|
|
1021
|
+
// with f inside the interval and converges to the next integer at f → 1
|
|
1022
|
+
checkBool("h21(10,2.001) < h21(10,2.5) < h21(10,2.99) < h21(10,3)",
|
|
1023
|
+
MetaNum(10).h21(2.001).lt(MetaNum(10).h21(2.5)) &&
|
|
1024
|
+
MetaNum(10).h21(2.5).lt(MetaNum(10).h21(2.99)) &&
|
|
1025
|
+
MetaNum(10).h21(2.99).lt(MetaNum(10).h21(3)), true);
|
|
1026
|
+
checkBool("h31(10,5.1) < h31(10,5.5) < h31(10,5.9) < h31(10,6)",
|
|
1027
|
+
MetaNum(10).h31(5.1).lt(MetaNum(10).h31(5.5)) &&
|
|
1028
|
+
MetaNum(10).h31(5.5).lt(MetaNum(10).h31(5.9)) &&
|
|
1029
|
+
MetaNum(10).h31(5.9).lt(MetaNum(10).h31(6)), true);
|
|
1030
|
+
// the expanded form keeps the count law: every row below the top one carries
|
|
1031
|
+
// x-2, and the α-1 row carries y-2 — a fractional y-2, which is what makes
|
|
1032
|
+
// h21(10,2+ε) start at 10{ω*2}10 and grow to 10{ω*2}10{ω*2}10 at y = 3
|
|
1033
|
+
(function () {
|
|
1034
|
+
var ok = true;
|
|
1035
|
+
for (var k = 0; k < 6; k++) {
|
|
1036
|
+
var fy = [2.001, 2.1, 2.5, 3.5, 10.25, 100.75][k];
|
|
1037
|
+
var rr = MetaNum(10).h21(fy).array.slice(1);
|
|
1038
|
+
for (var i = 0; i < rr.length - 1; i++) if (rr[i][0] !== 8) ok = false;
|
|
1039
|
+
if (Math.abs(rr[rr.length - 1][0] - (fy - 2)) > 1e-9) ok = false;
|
|
1040
|
+
}
|
|
1041
|
+
checkBool("h21(10, fractional): lower rows = x-2 = 8, ω*2 row = y-2", ok, true);
|
|
1042
|
+
// the endpoints: 2+ε is (just above) h21(10,2) = 10{ω*2}10, 3-ε → h21(10,3)
|
|
1043
|
+
checkBool("h21(10,2+1e-15) = 10{ω*2}10 cascade + a vanishing ω*2 row",
|
|
1044
|
+
MetaNum(10).h21(2 + 1e-15).array.length === 12 &&
|
|
1045
|
+
MetaNum(10).h21(2 + 1e-15).array[11][0] < 1e-9, true);
|
|
1046
|
+
checkBool("h21(10,2.999999) → h21(10,3) from below",
|
|
1047
|
+
MetaNum(10).h21(2.999999).lt(MetaNum(10).h21(3)) &&
|
|
1048
|
+
MetaNum(10).h21(2.999999).gt(MetaNum(10).h21(2)), true);
|
|
1049
|
+
})();
|
|
1050
|
+
// row coefficients stay integer (a fractional constant is carried to the base)
|
|
1051
|
+
(function () {
|
|
1052
|
+
var ok = true;
|
|
1053
|
+
for (var f of ["h21", "h22", "h31", "h101", "h111", "h1001"]) {
|
|
1054
|
+
for (var k = 0; k < 5; k++) {
|
|
1055
|
+
var fy = [2.001, 2.5, 3.5, 10.25, 100.75][k];
|
|
1056
|
+
var arr = MetaNum(10)[f](fy).array;
|
|
1057
|
+
for (var i = 1; i < arr.length; i++) {
|
|
1058
|
+
for (var j = 1; j < arr[i].length; j++) {
|
|
1059
|
+
if (arr[i][j] !== Math.floor(arr[i][j])) ok = false;
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
checkBool("fractional y: every ordinal row coefficient is an integer", ok, true);
|
|
1065
|
+
})();
|
|
1066
|
+
|
|
1067
|
+
// no crash / NaN over the whole range with fractional operands
|
|
1068
|
+
(function () {
|
|
1069
|
+
var allOps = ["h20","h21","h22","h30","h31","h100","h101","h110","h111",
|
|
1070
|
+
"h1000","h1001","h10000","iterate"];
|
|
1071
|
+
var bad = 0;
|
|
1072
|
+
for (var i = 0; i < allOps.length; i++) {
|
|
1073
|
+
for (var b = 0; b < 4; b++) {
|
|
1074
|
+
var bx = [3, 10, 1e6, 1e16][b];
|
|
1075
|
+
for (var k = 0; k < 5; k++) {
|
|
1076
|
+
var by = [2.0001, 2.5, 3.5, 10.25, 1000.5][k];
|
|
1077
|
+
try {
|
|
1078
|
+
var v = MetaNum(bx)[allOps[i]](by);
|
|
1079
|
+
if (v.isNaN()) bad++;
|
|
1080
|
+
} catch (e) { bad++; }
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
checkBool("no throw/NaN for fractional y over h20..h10000 + iterate", bad === 0, true);
|
|
1085
|
+
})();
|
|
1086
|
+
|
|
1087
|
+
// inverse round-trip over the whole small-operand range, successors and limits
|
|
1088
|
+
(function () {
|
|
1089
|
+
var pairs = [["h11","inv_expande"],["h12","inv_multiexpande"],["h13","inv_powerexpande"],
|
|
1090
|
+
["h20","inv_aperioexpande"],["h21","inv_explode"],["h22","inv_multiexplode"],
|
|
1091
|
+
["h30","inv_aperioexplode"],["h31","inv_detonate"],["h100","inv_aperionate"],
|
|
1092
|
+
["h101","inv_megote"],["h110","inv_aperimegote"],["h111","inv_megoexpande"],
|
|
1093
|
+
["h1000","inv_aperiatote"],["h1001","inv_powiainate"]];
|
|
1094
|
+
var bad = 0, firstBad = "";
|
|
1095
|
+
for (var i = 0; i < pairs.length; i++) {
|
|
1096
|
+
for (var b = 0; b < 3; b++) {
|
|
1097
|
+
var bx = [3, 5, 10][b];
|
|
1098
|
+
for (var y = 3; y <= 20; y++) {
|
|
1099
|
+
var v = MetaNum(bx)[pairs[i][0]](y);
|
|
1100
|
+
if (!v[pairs[i][1]](MetaNum(bx)).eq(MetaNum(y))) {
|
|
1101
|
+
bad++; if (!firstBad) firstBad = pairs[i][0] + "(" + bx + "," + y + ")";
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
checkBool("inverse round-trip for h11..h1001 (x=3/5/10, y=3..20)", bad === 0,
|
|
1107
|
+
true, bad === 0 ? "" : " first failure: " + firstBad);
|
|
1108
|
+
})();
|
|
1109
|
+
|
|
1110
|
+
// ─────────────────────────────────────
|
|
1111
|
+
// engine arrays: the (y-2) count law
|
|
1112
|
+
// x{L}y = x{L-1}^{y-2}(x{L-1}x): 10{25}10 → count-8 rows/cols (the
|
|
1113
|
+
// canonical all-8s), 4{25}4 → count-2; truncation keeps the largest
|
|
1114
|
+
// maxRows-1 rows, second-kept row +1, first row [10]
|
|
1115
|
+
// ─────────────────────────────────────
|
|
1116
|
+
console.log("\n=== engine arrays ===");
|
|
1117
|
+
checkBool("10{25}10 exact: all-8s r0 + [8,20..24] rows",
|
|
1118
|
+
JSON.stringify(MetaNum.arrow(10, 25, 10).array)
|
|
1119
|
+
=== JSON.stringify([[10000000000,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8],
|
|
1120
|
+
[8,20],[8,21],[8,22],[8,23],[8,24]]), true);
|
|
1121
|
+
checkBool("4{25}4 exact: count-2 chain",
|
|
1122
|
+
JSON.stringify(MetaNum.arrow(4, 25, 4).array)
|
|
1123
|
+
=== JSON.stringify([[153.90699754796802,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2],
|
|
1124
|
+
[2,20],[2,21],[2,22],[2,23],[2,24]]), true);
|
|
1125
|
+
checkBool("10{10000}10 truncated: [9,9981],[8,9982]…[8,9999], r0 [10]",
|
|
1126
|
+
JSON.stringify(MetaNum.arrow(10, 10000, 10).array).indexOf("[[10],[9,9981],[8,9982],[8,9983]") === 0 &&
|
|
1127
|
+
JSON.stringify(MetaNum.arrow(10, 10000, 10).array.slice(-1)) === "[[8,9999]]", true);
|
|
1128
|
+
|
|
1129
|
+
// ─────────────────────────────────────
|
|
1130
|
+
// BEAF ordinal nesting (convention: BEAF(a,b,c,d)=a{ω*(d-1)+c}b —
|
|
1131
|
+
// the constant term keeps its value, ω+ coefficients decrement by 1)
|
|
752
1132
|
// Nested huge args anchor at the inner value and add one ordinal row:
|
|
753
|
-
// BEAF(inner,2,3,5) = inner{ω*4+
|
|
754
|
-
// BEAF(4,inner,3,5) = 4{ω*4+
|
|
1133
|
+
// BEAF(inner,2,3,5) = inner{ω*4+3}2 = inner{ω*4+2}inner → inner + [1|ω*4+2]
|
|
1134
|
+
// BEAF(4,inner,3,5) = 4{ω*4+3}inner → inner + [1|ω*4+3]
|
|
755
1135
|
// BEAF(4,2,inner,5) = 4{ω*4+inner}2 = 4{ω*5}inner → inner + [1|ω*5]
|
|
756
1136
|
// BEAF(4,2,3,inner) = 4{ω*inner+3}2 = 4{ω²}inner → inner + [1|ω²]
|
|
757
1137
|
// ─────────────────────────────────────
|
|
758
1138
|
console.log("\n=== BEAF ordinal nesting ===");
|
|
759
1139
|
checkOp("BEAF(3,3,2)", MetaNum.BEAF(3, 3, 2), 7625597484987, 0);
|
|
760
|
-
|
|
761
|
-
var beafInner = MetaNum.BEAF(4, 2, 3, 5); // 4{ω*4+2}2
|
|
762
|
-
checkBool("BEAF(4,2,3,5) top row [2,
|
|
763
|
-
JSON.stringify(beafInner.array[beafInner.array.length - 1]) === JSON.stringify([2,
|
|
1140
|
+
checkBool("BEAF(2,2,1,2)", MetaNum.BEAF(2, 2, 1, 2).eq(4), true);
|
|
1141
|
+
var beafInner = MetaNum.BEAF(4, 2, 3, 5); // 4{ω*4+3}2 = 4{ω*4+2}(4{ω*4+2}(4{ω*4+1}...))
|
|
1142
|
+
checkBool("BEAF(4,2,3,5) top row [2,1,4]",
|
|
1143
|
+
JSON.stringify(beafInner.array[beafInner.array.length - 1]) === JSON.stringify([2, 1, 4]), true);
|
|
764
1144
|
checkArr("BEAF(BEAF(4,2,3,5),2,3,5)", MetaNum.BEAF(beafInner, 2, 3, 5),
|
|
765
|
-
beafInner.array.concat([[1, 1, 4]]));
|
|
766
|
-
checkArr("BEAF(4,BEAF(4,2,3,5),3,5)", MetaNum.BEAF(4, beafInner, 3, 5),
|
|
767
1145
|
beafInner.array.concat([[1, 2, 4]]));
|
|
1146
|
+
checkArr("BEAF(4,BEAF(4,2,3,5),3,5)", MetaNum.BEAF(4, beafInner, 3, 5),
|
|
1147
|
+
beafInner.array.concat([[1, 3, 4]]));
|
|
768
1148
|
checkArr("BEAF(4,2,BEAF(4,2,3,5),5)", MetaNum.BEAF(4, 2, beafInner, 5),
|
|
769
1149
|
beafInner.array.concat([[1, 0, 5]]));
|
|
770
1150
|
checkArr("BEAF(4,2,3,BEAF(4,2,3,5))", MetaNum.BEAF(4, 2, 3, beafInner),
|
|
771
1151
|
beafInner.array.concat([[1, 0, 0, 1]]));
|
|
772
1152
|
var beafInner5 = MetaNum.BEAF(5, 5, 5, 5, 5);
|
|
773
|
-
// ω²-level huge arg: the outer keeps inner's ordinal rows
|
|
1153
|
+
// ω²-level huge arg: the outer keeps inner's ordinal rows except the smallest
|
|
1154
|
+
// (dropped at row capacity), base stays [10], first kept row count +1 (the
|
|
1155
|
+
// truncation marker), plus the new [1|ω⁴] anchor row
|
|
1156
|
+
var beafOuter5Exp = [[10]].concat(beafInner5.array.slice(2)).concat([[1, 0, 0, 0, 1]]);
|
|
1157
|
+
beafOuter5Exp[1] = beafOuter5Exp[1].slice();
|
|
1158
|
+
beafOuter5Exp[1][0] += 1;
|
|
774
1159
|
checkArr("BEAF(5,5,5,5,BEAF(5,5,5,5,5))", MetaNum.BEAF(5, 5, 5, 5, beafInner5),
|
|
775
|
-
|
|
1160
|
+
beafOuter5Exp);
|
|
1161
|
+
// ─────────────────────────────────────
|
|
1162
|
+
// BEAF(a,b,c,d,...) = a{...+ω^2*(e-1)+ω*(d-1)+c}b (constant term = args[2])
|
|
1163
|
+
// expansion: largest-to-smallest evaluation; exact when it fits maxRows-1
|
|
1164
|
+
// rows, else base [10] + first kept row count +1
|
|
1165
|
+
// ─────────────────────────────────────
|
|
1166
|
+
// {2,7,5,5} = 2{ω*4+5}7: rule 3 ends every limit step on the base 2, and
|
|
1167
|
+
// 2-2=0 means every cascade count vanishes; 2{α}2 collapses through
|
|
1168
|
+
// successors/limits down to the finite anchor 2{k}2=4 — result is exactly 4
|
|
1169
|
+
checkBool("BEAF(2,7,5,5) = 4 (base-2 rule-3 collapse)",
|
|
1170
|
+
MetaNum.BEAF(2, 7, 5, 5).eq(4), true);
|
|
1171
|
+
// {3,2,4,6} = 3{ω*5+4}2
|
|
1172
|
+
checkBool("BEAF(3,2,4,6) top row [1,2,5]",
|
|
1173
|
+
JSON.stringify(MetaNum.BEAF(3, 2, 4, 6).array[MetaNum.BEAF(3, 2, 4, 6).array.length - 1])
|
|
1174
|
+
=== JSON.stringify([1, 2, 5]), true);
|
|
1175
|
+
// BEAF(3,3,5,5,5) = 3{ω^2*4+ω*4+5}3: exact enumeration needs 49 ordinal rows
|
|
1176
|
+
// (> default maxRows=20), so raise the budget for this case only
|
|
1177
|
+
var _savedRowsBEAF = MetaNum.maxRows;
|
|
1178
|
+
MetaNum.maxRows = 100;
|
|
1179
|
+
var beaf35555 = MetaNum.BEAF(3, 3, 5, 5, 5);
|
|
1180
|
+
checkBool("BEAF(3,3,5,5,5) exact (base kept, [1,0,1] first, [1,4,4,4] last)",
|
|
1181
|
+
beaf35555.array.length <= MetaNum.maxRows
|
|
1182
|
+
&& JSON.stringify(beaf35555.array[0]) === JSON.stringify([3638334640023.7783, 7625597484984])
|
|
1183
|
+
&& JSON.stringify(beaf35555.array[1]) === JSON.stringify([1, 0, 1])
|
|
1184
|
+
&& JSON.stringify(beaf35555.array[beaf35555.array.length - 1]) === JSON.stringify([1, 4, 4, 4]), true);
|
|
1185
|
+
MetaNum.maxRows = _savedRowsBEAF;
|
|
1186
|
+
// BEAF(5,5,1,1,1,2) = 5{ω^3+1}5: truncated expansion
|
|
1187
|
+
var beaf511112 = MetaNum.BEAF(5, 5, 1, 1, 1, 2);
|
|
1188
|
+
checkBool("BEAF(5,5,1,1,1,2) truncated ([10] base, first count 4, last [3,0,0,0,1])",
|
|
1189
|
+
JSON.stringify(beaf511112.array[0]) === JSON.stringify([10])
|
|
1190
|
+
&& beaf511112.array[1][0] === 4
|
|
1191
|
+
&& JSON.stringify(beaf511112.array[beaf511112.array.length - 1]) === JSON.stringify([3, 0, 0, 0, 1])
|
|
1192
|
+
&& beaf511112.array.length === MetaNum.maxRows, true);
|
|
1193
|
+
|
|
1194
|
+
// ─────────────────────────────────────
|
|
1195
|
+
// Hardy hierarchy — ALL hardy verifications grouped here
|
|
1196
|
+
// reorganization: small-level, per-definition nested exponents, >1e15
|
|
1197
|
+
// inputs, MetaNum-object inputs and the 10^^MSI engine limit)
|
|
1198
|
+
// hardy(n) = H_α(10); hardy(10) = H_ω(10) = 20; digits of n become CNF coefficients
|
|
1199
|
+
// hardy per definition, evaluated from below
|
|
1200
|
+
// hardy(1e10) = H_{ω^ω}(10) = H_{ω^10}(10) — EXACT array
|
|
1201
|
+
// [3086.036065328153, 9×8], strictly below 10{10}10
|
|
1202
|
+
// hardy(1e11) = H_{ω^(ω+1)}(10) — expande(10,10)'s row structure on the
|
|
1203
|
+
// definitional base, strictly below 10{ω+1}10
|
|
1204
|
+
// monotone: hardy(9999999999) < hardy(1e10) < hardy(10000000001)
|
|
1205
|
+
// (moved into the "hardy hierarchy (all cases)" section below
|
|
1206
|
+
// reorganization groups every hardy verification together)
|
|
1207
|
+
// ─────────────────────────────────────
|
|
1208
|
+
console.log("\n=== hardy hierarchy (all cases) ===");
|
|
1209
|
+
// -- small levels (exact closed forms) --
|
|
1210
|
+
checkOp("hardy(0)", MetaNum.hardy(0), 10, 0);
|
|
1211
|
+
checkOp("hardy(9)", MetaNum.hardy(9), 19, 0);
|
|
1212
|
+
checkBool("hardy(10) = H_ω(10) = 20", MetaNum.hardy(10).eq(20), true);
|
|
1213
|
+
checkBool("hardy(11) = H_{ω+1}(10) = 22", MetaNum.hardy(11).eq(22), true);
|
|
1214
|
+
checkBool("hardy(20) = H_{ω*2}(10) = 40", MetaNum.hardy(20).eq(40), true);
|
|
1215
|
+
checkBool("hardy(99) = H_{ω*9+9}(10) = 9728", MetaNum.hardy(99).eq(9728), true);
|
|
1216
|
+
checkBool("hardy(100) = H_{ω^2}(10) = 10240", MetaNum.hardy(100).eq(10240), true);
|
|
1217
|
+
checkBool("hardy(101) = H_{ω^2+1}(10) = 22528", MetaNum.hardy(101).eq(22528), true);
|
|
1218
|
+
checkBool("hardy(1234) = H_{ω^3+ω^2*2+ω*3+4}(10) > 10↑↑1000",
|
|
1219
|
+
MetaNum.hardy(1234).gt(MetaNum(10).arrow(2)(1000)), true);
|
|
1220
|
+
checkBool("hardy monotone: 999 < 1000", MetaNum.hardy(999).lt(MetaNum.hardy(1000)), true);
|
|
1221
|
+
checkBool("hardy(12345) > hardy(1234)", MetaNum.hardy(12345).gt(MetaNum.hardy(1234)), true);
|
|
1222
|
+
// -- nested exponents, per definition & evaluated from below (v2.0) --
|
|
1223
|
+
checkBool("hardy(1e10) = H_{ω^10}(10) exact array [3086.036, 9×8]",
|
|
1224
|
+
JSON.stringify(MetaNum.hardy(1e10).array)
|
|
1225
|
+
=== JSON.stringify([[3086.036065328153, 9, 9, 9, 9, 9, 9, 9, 9]]), true);
|
|
1226
|
+
checkBool("hardy(1e10) < 10{10}10",
|
|
1227
|
+
MetaNum.hardy(1e10).lt(MetaNum(10).arrow(10)(10)), true);
|
|
1228
|
+
checkBool("hardy(1e11) = H_{ω^(ω+1)}(10) < 10{ω+1}10 (expande)",
|
|
1229
|
+
MetaNum.hardy(1e11).lt(MetaNum(10).expande(10)), true);
|
|
1230
|
+
checkBool("hardy monotone 9999999999 < 1e10 < 10000000001",
|
|
1231
|
+
MetaNum.hardy(9999999999).lt(MetaNum.hardy(1e10))
|
|
1232
|
+
&& MetaNum.hardy(1e10).lt(MetaNum.hardy(10000000001)), true);
|
|
1233
|
+
checkBool("hardy(1e12) > hardy(1e11) (monotone in scale)",
|
|
1234
|
+
MetaNum.hardy(1e12).gt(MetaNum.hardy(1e11)), true);
|
|
1235
|
+
// -- >1e15 inputs (v2.0): scientific-notation strings expand to exact
|
|
1236
|
+
// digits so the digit-CNF reading stays monotone past 1e20 --
|
|
1237
|
+
checkBool("hardy(1e20) < hardy(1e21) < hardy(1e22) (sci-string fix)",
|
|
1238
|
+
MetaNum.hardy(1e20).lt(MetaNum.hardy(1e21))
|
|
1239
|
+
&& MetaNum.hardy(1e21).lt(MetaNum.hardy(1e22)), true);
|
|
1240
|
+
checkBool("hardy(1e15) < hardy(1e16) < hardy(1e17)",
|
|
1241
|
+
MetaNum.hardy(1e15).lt(MetaNum.hardy(1e16))
|
|
1242
|
+
&& MetaNum.hardy(1e16).lt(MetaNum.hardy(1e17)), true);
|
|
1243
|
+
// -- MetaNum-object input (v2.0): structures shadow to their ordinal --
|
|
1244
|
+
// power tower 10^^k → ω^ω^…^ω (k ω's) → H there = 10.epsilonate(k);
|
|
1245
|
+
// letter/ordinal values sit at their own Hardy position → themselves
|
|
1246
|
+
checkBool("hardy(10^^100) = 10{ω^…^ω(100 ωs)}10 = epsilonate(100)",
|
|
1247
|
+
MetaNum.hardy(MetaNum(10).tetr(100)).eq(MetaNum(10).epsilonate(100)), true);
|
|
1248
|
+
checkBool("hardy(MetaNum G600) = Infinity",
|
|
1249
|
+
MetaNum.hardy(MetaNum("G600")).eq(MetaNum.infinity), true);
|
|
1250
|
+
checkBool("hardy(MetaNum arrow(3,9,3)) = Infinity",
|
|
1251
|
+
MetaNum.hardy(MetaNum.arrow(3, 9, 3)).eq(MetaNum.infinity), true);
|
|
1252
|
+
// anything strictly above 10^^MSI exceeds the ε₀ ceiling → Infinity
|
|
1253
|
+
checkBool("hardy(10{3}10) = Infinity (> 10^^MSI)",
|
|
1254
|
+
MetaNum.hardy(MetaNum(10).arrow(3)(10)).isInfinite(), true);
|
|
1255
|
+
// -- the engine limit: hardy(10^^MSI) = 10{ω^…^ω(MSI ω's)}10 (v2.0) --
|
|
1256
|
+
(function () {
|
|
1257
|
+
var MSI = 9007199254740991;
|
|
1258
|
+
checkBool("hardy(10^^MSI) = MetaNum limit 10{ω^…^ω(MSI ω's)}10",
|
|
1259
|
+
MetaNum.hardy(MetaNum(10).tetr(MSI)).eq(MetaNum(10).epsilonate(MSI)), true);
|
|
1260
|
+
checkBool("hardy(10^^(MSI-1)) = epsilonate(MSI-1) (just below the cap)",
|
|
1261
|
+
MetaNum.hardy(MetaNum(10).tetr(MSI - 1)).eq(MetaNum(10).epsilonate(MSI - 1)), true);
|
|
1262
|
+
})();
|
|
1263
|
+
|
|
1264
|
+
// ─────────────────────────────────────
|
|
1265
|
+
// fractional hyperoperation levels
|
|
1266
|
+
// level n+f interpolates geometrically (README rule i): 10{n+f}10 =
|
|
1267
|
+
// 10{n+1}(2·5^f); continuous: f=0 → level n, f=1 → level n+1
|
|
1268
|
+
// ─────────────────────────────────────
|
|
1269
|
+
console.log("\n=== fractional levels ===");
|
|
1270
|
+
(function () {
|
|
1271
|
+
var a = MetaNum(10);
|
|
1272
|
+
var v3 = a.arrow(3)(10), v4 = a.arrow(4)(10);
|
|
1273
|
+
var v32 = a.arrow(3.2)(10), v35 = a.arrow(3.5)(10);
|
|
1274
|
+
checkBool("10{3.0}10 = 10{3}10 (f=0 anchor)", a.arrow(3.0)(10).eq(v3), true);
|
|
1275
|
+
checkBool("monotone 10{3}10 < 10{3.2}10 < 10{3.5}10 < 10{4}10",
|
|
1276
|
+
v3.lt(v32) && v32.lt(v35) && v35.lt(v4), true);
|
|
1277
|
+
// rule (i) verbatim: 10{3.5}10 = 10{4}(2·5^0.5)
|
|
1278
|
+
var theta = MetaNum(2).mul(MetaNum(10).div(2).pow(0.5));
|
|
1279
|
+
checkBool("10{3.5}10 = 10{4}(2·5^0.5)", v35.eq(a.arrow(4)(theta)), true);
|
|
1280
|
+
checkBool("3{2.5}3 between 3{2}3 and 3{3}3",
|
|
1281
|
+
MetaNum(3).arrow(2)(3).lt(MetaNum(3).arrow(2.5)(3)) &&
|
|
1282
|
+
MetaNum(3).arrow(2.5)(3).lt(MetaNum(3).arrow(3)(3)), true);
|
|
1283
|
+
})();
|
|
1284
|
+
|
|
1285
|
+
// ─────────────────────────────────────
|
|
1286
|
+
// non-integer arguments at ordinal levels
|
|
1287
|
+
// expa(10,2.1) = 10{ω+1}2.1 = 10{ω}10{ω}(10^0.1)
|
|
1288
|
+
// (continuity: expa(10,2) = 10{ω}10, expa(10,3) = 10{ω}10{ω}10)
|
|
1289
|
+
// ─────────────────────────────────────
|
|
1290
|
+
console.log("\n=== ordinal-level fractional arguments ===");
|
|
1291
|
+
(function () {
|
|
1292
|
+
var e2 = MetaNum(10).expande(2), e21 = MetaNum(10).expande(2.1),
|
|
1293
|
+
e25 = MetaNum(10).expande(2.5), e3 = MetaNum(10).expande(3);
|
|
1294
|
+
checkBool("expa(10,2) = 10{ω}10", e2.eq(MetaNum(10).aperiote(10)), true);
|
|
1295
|
+
checkBool("expa(10,3) = 10{ω}10{ω}10", e3.eq(MetaNum(10).aperiote(e2)), true);
|
|
1296
|
+
checkBool("expa(10,2.1) = 10{ω}10{ω}(10^0.1)",
|
|
1297
|
+
e21.eq(MetaNum(10).aperiote(MetaNum(10).aperiote(MetaNum(10).pow(0.1)))), true);
|
|
1298
|
+
checkBool("expa monotone 2 < 2.1 < 2.5 < 3",
|
|
1299
|
+
e2.lt(e21) && e21.lt(e25) && e25.lt(e3), true);
|
|
1300
|
+
var m21 = MetaNum(10).multiexpande(2.1);
|
|
1301
|
+
checkBool("muea(10,2.1) = 10{ω+2}2.1 = (10{ω+1})²(10^0.1)",
|
|
1302
|
+
m21.eq(MetaNum(10).expande(MetaNum(10).expande(MetaNum(10).pow(0.1)))), true);
|
|
1303
|
+
checkBool("poea(10,2.1) = 10{ω+3}2.1 = (10{ω+2})²(10^0.1)",
|
|
1304
|
+
MetaNum(10).powerexpande(2.1).eq(
|
|
1305
|
+
MetaNum(10).multiexpande(MetaNum(10).multiexpande(MetaNum(10).pow(0.1)))), true);
|
|
1306
|
+
checkBool("expa(10,3.1) computable", !MetaNum(10).expande(3.1).isNaN(), true);
|
|
1307
|
+
})();
|
|
1308
|
+
|
|
776
1309
|
console.log("\n=== Done ===");
|
|
777
1310
|
|
|
778
1311
|
// ─────────────────────────────────────
|
|
@@ -810,12 +1343,12 @@ checkFormat("GG900", "GG900", "G1.000G900");
|
|
|
810
1343
|
checkFormat("J1000", "J1000", "1.000J1,000");
|
|
811
1344
|
|
|
812
1345
|
// Ordinal (Aa and beyond) - single letter: α + letter + β
|
|
813
|
-
checkFormat("Aa100", "Aa100", "
|
|
1346
|
+
checkFormat("Aa100", "Aa100", "2.000Aa100");
|
|
814
1347
|
checkFormat("Ab400", "Ab400", "1.000Ab400");
|
|
815
1348
|
checkFormat("Ac800", "Ac800", "1.000Ac800");
|
|
816
1349
|
checkFormat("Aj900", "Aj900", "1.000Aj900");
|
|
817
|
-
checkFormat("Ba1000", "Ba1000", "
|
|
818
|
-
checkFormat("Aaa100", "Aaa100", "
|
|
1350
|
+
checkFormat("Ba1000", "Ba1000", "2.000Ba1,000");
|
|
1351
|
+
checkFormat("Aaa100", "Aaa100", "2.000Aaa100");
|
|
819
1352
|
|
|
820
1353
|
// Ordinal with multi-level r0: ordinalLetter + r0Chain (includes α)
|
|
821
1354
|
checkFormat("AaE200", "AaE200", "Aa1.000E200");
|
|
@@ -831,15 +1364,13 @@ checkFormat("Abc100", "Abc100", "1.000Abc100");
|
|
|
831
1364
|
checkFormat("Defg200", "Defg200", "1.000Defg200");
|
|
832
1365
|
|
|
833
1366
|
// Symbols and ε:
|
|
834
|
-
checkFormat("!Aa300", "!Aa300", "!
|
|
1367
|
+
checkFormat("!Aa300", "!Aa300", "!2.000Aa300");
|
|
835
1368
|
checkFormat("@Bb400", "@Bb400", "@1.000Bb400");
|
|
836
1369
|
checkFormat("1ε500", "1ε500", "1.000ε500");
|
|
837
1370
|
|
|
838
|
-
// ─────────────────────────────────────
|
|
839
1371
|
// Reciprocal of large numbers (sign=2) format tests
|
|
840
1372
|
// smallNotationUseE=true → E-<formatted mag>
|
|
841
1373
|
// smallNotationUseE=false → <formatted value>⁻¹
|
|
842
|
-
// ─────────────────────────────────────
|
|
843
1374
|
console.log("\n=== reciprocal format tests ===");
|
|
844
1375
|
|
|
845
1376
|
// Parsing: verify sign=2 and array structure
|
|
@@ -863,12 +1394,312 @@ checkFormat("1/F10 (useE=true)", "1/F10", "E-1.000F9");
|
|
|
863
1394
|
// 1/F500 → "1.000F500⁻¹"
|
|
864
1395
|
// 1/G200 → "1.000G200⁻¹"
|
|
865
1396
|
// 1/F10 → "1.000F10⁻¹"
|
|
866
|
-
var
|
|
867
|
-
|
|
1397
|
+
var _FMT = (typeof FORMAT_OPTIONS !== "undefined" && FORMAT_OPTIONS) ? FORMAT_OPTIONS : require("./format-metanum.js").FORMAT_OPTIONS;
|
|
1398
|
+
var _savedUseE = _FMT.smallNotationUseE;
|
|
1399
|
+
_FMT.smallNotationUseE = false;
|
|
868
1400
|
checkFormat("E-EE1000 (useE=false)", "E-EE1000", "EE1.000E1,000⁻¹");
|
|
869
1401
|
checkFormat("1/F500 (useE=false)", "1/F500", "1.000F500⁻¹");
|
|
870
1402
|
checkFormat("1/G200 (useE=false)", "1/G200", "1.000G200⁻¹");
|
|
871
1403
|
checkFormat("1/F10 (useE=false)", "1/F10", "1.000F10⁻¹");
|
|
872
|
-
|
|
1404
|
+
_FMT.smallNotationUseE = _savedUseE;
|
|
1405
|
+
|
|
1406
|
+
console.log("\n=== format α correctness ===");
|
|
1407
|
+
// format α correctness
|
|
1408
|
+
checkFormat("hardy(1120) single α", MetaNum.hardy(1120), "F4.398E13");
|
|
1409
|
+
checkFormat("hardy(4150) real α", MetaNum.hardy(4150), "2.300G5");
|
|
1410
|
+
checkFormat("nested arrow single α", MetaNum.arrow(3, MetaNum.arrow(3, 4, 3), 3), "AaGF7.626E12");
|
|
1411
|
+
checkFormat("canonical all-8s keeps α=1 (G600)", "G600", "1.000G600");
|
|
1412
|
+
|
|
1413
|
+
// ─────────────────────────────────────
|
|
1414
|
+
// display rules: at most TWO letter types, one α, multiLetterLimit symbol
|
|
1415
|
+
// carry — a cascade that would spell 20 letter types keeps its top two levels,
|
|
1416
|
+
// and a combination longer than multiLetterLimit switches to !αAaβ
|
|
1417
|
+
// ─────────────────────────────────────
|
|
1418
|
+
checkFormat("20-row cascade compresses to two letter types", MetaNum.h10000(3, 10), "Iccc1.000Iccb10");
|
|
1419
|
+
checkFormat("10-letter level carries to !…Aa9 (definition digits)", MetaNum.iter(3, 10), "!2.222Aa9");
|
|
1420
|
+
checkFormat("5-letter level carries to !…Aa4 (definition digits)", m3.iter(5), "!2.222Aa4");
|
|
1421
|
+
checkFormat("symbol carry stacks: apix(3,10) → @…Aa10", m3.aperixxate(10), "@2.000Aa10");
|
|
1422
|
+
checkFormat("symbol carry stacks: apix(3,5) → @…Aa5", m3.aperixxate(5), "@2.000Aa5");
|
|
1423
|
+
checkFormat("short diagonal keeps the letter form", m3.aperixxate(3), "!2.000Aaaa10");
|
|
1424
|
+
checkFormat("cascade inner α stays [1,10) (AbAa600)", "AbAa600", "Ab1.000Aa600");
|
|
1425
|
+
|
|
1426
|
+
// ─────────────────────────────────────
|
|
1427
|
+
// issue #14: stacking the SAME function must nest the letter — the rows are a
|
|
1428
|
+
// composition, so the top row leads and the row below it (which collapses from
|
|
1429
|
+
// its repeat count) keeps the single α and β:
|
|
1430
|
+
// poea(10,poea(10,100)) = Ad(Ad(99)) → "Ad1.000Ad99" (not "1.000Ad114")
|
|
1431
|
+
// ─────────────────────────────────────
|
|
1432
|
+
var stacked = [
|
|
1433
|
+
["expande (ω+1)", "expande", "2.398Ab99", "Ab2.398Ab99"],
|
|
1434
|
+
["multiexpande (ω+2)", "multiexpande", "1.000Ac99", "Ac1.000Ac99"],
|
|
1435
|
+
["powerexpande (ω+3)", "powerexpande", "1.000Ad99", "Ad1.000Ad99"],
|
|
1436
|
+
["explode (ω*2+1)", "explode", "1.000Bb99", "Bb1.000Bb99"],
|
|
1437
|
+
["multiexplode (ω*2+2)", "multiexplode", "1.000Bc99", "Bc1.000Bc99"],
|
|
1438
|
+
["megoexpande (ω²+1)", "megoexpande", "1.000Abb99", "Abb1.000Abb99"],
|
|
1439
|
+
["multimegote (ω²+2)", "multimegote", "1.000Aac99", "Aac1.000Aac99"],
|
|
1440
|
+
["powiainate (ω³+1)", "powiainate", "1.000Aaab99", "Aaab1.000Aaab99"]
|
|
1441
|
+
];
|
|
1442
|
+
for (var si = 0; si < stacked.length; si++) {
|
|
1443
|
+
var sf = stacked[si][1], s1 = MetaNum(10)[sf](100), s2 = MetaNum(10)[sf](s1), s3 = MetaNum(10)[sf](s2);
|
|
1444
|
+
checkFormat("stacked " + stacked[si][0] + " (1st)", s1, stacked[si][2]);
|
|
1445
|
+
checkFormat("stacked " + stacked[si][0] + " (x2)", s2, stacked[si][3]);
|
|
1446
|
+
checkBool("stacked " + stacked[si][0] + " grows and keeps nesting",
|
|
1447
|
+
s2.gt(s1) && s3.gt(s2) && format(s3).indexOf(format(s2).slice(0, 2)) === 0, true);
|
|
1448
|
+
}
|
|
1449
|
+
// apea (ω*2) with an operand above MSI: apea(apea(a)) must stay visible
|
|
1450
|
+
(function () {
|
|
1451
|
+
var p1 = MetaNum(10).aperioexpande(MetaNum(1e16));
|
|
1452
|
+
var p2 = MetaNum(10).aperioexpande(p1);
|
|
1453
|
+
var p3 = MetaNum(10).aperioexpande(p2);
|
|
1454
|
+
checkFormat("apea(1e16) (ω*2 level = Ba)", p1, "Ba1.000E16");
|
|
1455
|
+
checkFormat("apea(apea(1e16)) nests", p2, "BaBa1.000E16");
|
|
1456
|
+
checkFormat("apea^3(1e16) nests further", p3, "BaBaBa1.000E16");
|
|
1457
|
+
checkBool("apea stacking is strictly monotone", p2.gt(p1) && p3.gt(p2), true);
|
|
1458
|
+
})();
|
|
1459
|
+
// a row coefficient above 25 (ω+81 from a ω*2 fundamental sequence) has no
|
|
1460
|
+
// letter in the grid — clamp down instead of wrapping into a higher letter
|
|
1461
|
+
checkFormat("ω*2 level reads Ba (no coefficient wrap)", MetaNum(10).aperioexpande(100), "1.000Ba154");
|
|
1462
|
+
|
|
1463
|
+
// Γ-canonical law test: long descending count-1 chains
|
|
1464
|
+
// format at their bisect-exact letter on the engine's smooth arrow curve;
|
|
1465
|
+
// ordinal-row levels use Aa-notation (the engine's fractional-arg curve is
|
|
1466
|
+
// quantized at level ≥ 20, so 3{20}3 formats via its [1,20] ordinal row)
|
|
1467
|
+
checkFormat("GE12 single-alpha", "GE12", "G1.000E12");
|
|
1468
|
+
checkFormat("arrow(3,19,3) structural V...U...", MetaNum.arrow(3, 19, 3), "V2.376U2");
|
|
1469
|
+
checkFormat("arrow(3,20,3) structural W...V...", MetaNum.arrow(3, 20, 3), "W2.376V2");
|
|
1470
|
+
checkFormat("arrow(3,1000,3) αAaβ", MetaNum.arrow(3, 1000, 3), "2.376Aa999");
|
|
1471
|
+
|
|
1472
|
+
// ─────────────────────────────────────
|
|
1473
|
+
// maxCols/maxRows = 20 — r0 overflow levels must become
|
|
1474
|
+
// finite-level ordinal rows [count, level], not be dropped
|
|
1475
|
+
// ─────────────────────────────────────
|
|
1476
|
+
console.log("\n=== maxCols/maxRows = 20 (Z10) ===");
|
|
1477
|
+
var _savedCols = MetaNum.maxCols, _savedRows = MetaNum.maxRows;
|
|
1478
|
+
MetaNum.maxCols = 20; MetaNum.maxRows = 20;
|
|
1479
|
+
(function () {
|
|
1480
|
+
var exp = [[10000000000]];
|
|
1481
|
+
for (var i = 0; i < 19; i++) exp[0].push(8);
|
|
1482
|
+
var z20 = new MetaNum("Z10");
|
|
1483
|
+
checkArr("Z10 @ maxCols=20", z20, exp.concat([[8, 20], [8, 21]]));
|
|
1484
|
+
var z20rt = new MetaNum(z20.toString());
|
|
1485
|
+
checkBool("Z10 @ maxCols=20 roundtrip", z20.eq(z20rt), true);
|
|
1486
|
+
MetaNum.maxCols = 100; MetaNum.maxRows = 100;
|
|
1487
|
+
var z20v100 = new MetaNum(z20.toString());
|
|
1488
|
+
checkBool("Z10 @20 toString reparsed @100 ~= Z10 @100", z20v100.eq(new MetaNum("Z10")), true);
|
|
1489
|
+
})();
|
|
1490
|
+
MetaNum.maxCols = _savedCols; MetaNum.maxRows = _savedRows;
|
|
1491
|
+
|
|
1492
|
+
// ─────────────────────────────────────
|
|
1493
|
+
// symbol layer semantics (numeric-level assertions)
|
|
1494
|
+
// ! = one ω^ layer: !Aa5 = 10{ω^ω}5 = 10{ω^5}5 (FS of ω^ω at 5)
|
|
1495
|
+
// @ = two layers: @Aa5 = 10{ω^ω^ω}5 = 10{ω^(ω^5)}5
|
|
1496
|
+
// # = three layers; !Ab5 = 10{ω^(ω+1)}5
|
|
1497
|
+
// ─────────────────────────────────────
|
|
1498
|
+
console.log("\n=== symbol layer semantics ===");
|
|
1499
|
+
(function () {
|
|
1500
|
+
var om5row = JSON.stringify([1, 0, 0, 0, 0, 0, 1]); // [1 | ω^5] marker row
|
|
1501
|
+
var x = MetaNum("!Aa5");
|
|
1502
|
+
checkBool("!Aa5 = 10{ω^5}5 marker row", JSON.stringify(x.array[1]) === om5row && x.array.length === 2, true);
|
|
1503
|
+
checkBool("!Aa5 de-layers to Aaaaaa5", x.eq(MetaNum("Aaaaaa5")), true);
|
|
1504
|
+
checkBool("!1.000Aa5 = !Aa5 (binary form α=1)", MetaNum("!1.000Aa5").eq(x), true);
|
|
1505
|
+
var y = MetaNum("@Aa5");
|
|
1506
|
+
checkBool("@Aa5 = !Aaaaaa5 (two ω^ layers)", y.eq(MetaNum("!Aaaaaa5")), true);
|
|
1507
|
+
checkBool("@Aa5 layer=1 with ω^5 row", y.layer === 1 && JSON.stringify(y.array[1]) === om5row, true);
|
|
1508
|
+
checkBool("@1.000Aa5 = @Aa5", MetaNum("@1.000Aa5").eq(y), true);
|
|
1509
|
+
var z = MetaNum("#Aa5");
|
|
1510
|
+
checkBool("#Aa5 = @Aaaaaa5 (three ω^ layers)", z.eq(MetaNum("@Aaaaaa5")), true);
|
|
1511
|
+
checkBool("#Aa5 layer=2", z.layer === 2, true);
|
|
1512
|
+
var ab = MetaNum("!Ab5");
|
|
1513
|
+
checkBool("!Ab5 = 10{ω^(ω+1)}5 (layer 1, row [1,1,1])",
|
|
1514
|
+
ab.layer === 1 && JSON.stringify(ab.array[1]) === JSON.stringify([1, 1, 1]), true);
|
|
1515
|
+
checkBool("!Ba5 = 10{ω^(ω*2)}5 (layer 1, row [1,0,2])",
|
|
1516
|
+
MetaNum("!Ba5").layer === 1 && JSON.stringify(MetaNum("!Ba5").array[1]) === JSON.stringify([1, 0, 2]), true);
|
|
1517
|
+
checkBool("layer monotonicity Aa5 < !Aa5 < @Aa5 < #Aa5",
|
|
1518
|
+
MetaNum("Aa5").lt(x) && x.lt(y) && y.lt(z), true);
|
|
1519
|
+
checkBool("!Ab5 > !Aa5", ab.gt(x), true);
|
|
1520
|
+
checkRT("!Aa5", "!Aa5");
|
|
1521
|
+
checkRT("@Aa5", "@Aa5");
|
|
1522
|
+
checkRT("#Aa5", "#Aa5");
|
|
1523
|
+
checkRT("!Ab5", "!Ab5");
|
|
1524
|
+
})();
|
|
1525
|
+
|
|
1526
|
+
console.log("\n=== two-letter rule ===");
|
|
1527
|
+
(function () {
|
|
1528
|
+
// Rule (2-letter rule): a display may use at most 2 letter COMBINATIONS in its
|
|
1529
|
+
// finite hyper-op chain — VαEβ → VαFβ → … → VαVβ — never a third type mixed
|
|
1530
|
+
// in (e.g. "VFαEβ"). The rule is about the single-uppercase finite letters
|
|
1531
|
+
// (E,F,G,...,Z): the Aa/Ab/... two-char tokens are ordinal-structure
|
|
1532
|
+
// markers (same role as !/@/#! symbols), and an "E" inside a number
|
|
1533
|
+
// ("7.626E12") is scientific notation, not a letter op — both are excluded
|
|
1534
|
+
// from the count. The reference formatter (format-powiainanum.js) produces
|
|
1535
|
+
// the same shapes: "J" + "GF7.626E12" for arrow(3,arrow(3,4,3),3).
|
|
1536
|
+
var samples = ["V10", "VE10", "VF10", "W10", "G1.161G897", "AaGF7.626E12",
|
|
1537
|
+
"2.397G5", "1.285H8", "2.376W2", "1.125Aa99", "F4.398E13", "GF7.626E12"];
|
|
1538
|
+
var allOk = true;
|
|
1539
|
+
for (var i = 0; i < samples.length; i++) {
|
|
1540
|
+
var disp = format(MetaNum(samples[i]));
|
|
1541
|
+
// strip scientific-notation E inside numbers ("7.626E12"), then count
|
|
1542
|
+
// distinct single-uppercase letters (Aa-style ordinal tokens excluded)
|
|
1543
|
+
var stripped = disp.replace(/(\d(?:\.\d+)?)E(\d[\d,]*)/g, "$1$2");
|
|
1544
|
+
var tokens = stripped.match(/[A-Z](?![a-z])/g) || [];
|
|
1545
|
+
var types = {};
|
|
1546
|
+
for (var t = 0; t < tokens.length; t++) types[tokens[t]] = true;
|
|
1547
|
+
var nTypes = Object.keys(types).length;
|
|
1548
|
+
if (nTypes > 2) {
|
|
1549
|
+
allOk = false;
|
|
1550
|
+
console.log(" >2 finite letter types in", samples[i], "→", disp);
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
checkBool("all displays use ≤ 2 finite letter types", allOk, true);
|
|
1554
|
+
checkBool("arrow(3,4.1,3) display has exactly G only (VαEβ→…→VαVβ law)",
|
|
1555
|
+
(format(MetaNum.arrow(3, 4.1, 3)).match(/[A-Z][a-z]?/g) || []).every(function (tk) { return tk === "G"; }), true);
|
|
1556
|
+
// round-trip of the Aa-prefixed sci-arg chain (parse bug fix in v2.0:
|
|
1557
|
+
// "AaGF7.626E12" used to eat only the "7" and drop ".626E12")
|
|
1558
|
+
checkBool("AaGF7.626E12 parses with full sci arg",
|
|
1559
|
+
MetaNum("AaGF7.626E12").array[0][1] === 7625999999998
|
|
1560
|
+
&& MetaNum("AaGF7.626E12").array.length === 2, true);
|
|
1561
|
+
checkBool("AaGF7.626E12 round-trips through format",
|
|
1562
|
+
format(MetaNum(format(MetaNum("AaGF7.626E12")))) === "AaGF7.626E12", true);
|
|
1563
|
+
})();
|
|
1564
|
+
|
|
1565
|
+
// ─────────────────────────────────────
|
|
1566
|
+
// hardy hierarchy — display-form verification (all user cases)
|
|
1567
|
+
// ≤2 letter types per display; diagonal cascades compress to the
|
|
1568
|
+
// structural two-letter form or the αAaβ polarize diagonal;
|
|
1569
|
+
// repeatLetterThreshold+1 repeated single letters carry to the next
|
|
1570
|
+
// ─────────────────────────────────────
|
|
1571
|
+
console.log("\n=== hardy hierarchy display forms ===");
|
|
1572
|
+
checkFormat("arrow(3,9,3) → L…K…", MetaNum.arrow(3, 9, 3), "L2.376K2");
|
|
1573
|
+
checkFormat("arrow(3,10,3) → M(10^0.376)L2", MetaNum.arrow(3, 10, 3), "M2.376L2");
|
|
1574
|
+
checkFormat("arrow(4,9,4) → LLK…K…", MetaNum.arrow(4, 9, 4), "LLK3.550K3");
|
|
1575
|
+
checkFormat("arrow(5,9,5) → LLLKK…K…", MetaNum.arrow(5, 9, 5), "LLLKK4.669K4");
|
|
1576
|
+
checkBool("arrow(6,9,6) carries to …M5 (threshold+1 repeats)",
|
|
1577
|
+
/M5$/.test(format(MetaNum.arrow(6, 9, 6))), true);
|
|
1578
|
+
checkFormat("arrow(3,22,3) → Y…X…", MetaNum.arrow(3, 22, 3), "Y2.376X2");
|
|
1579
|
+
checkFormat("arrow(3,23,3) → Z…Y…", MetaNum.arrow(3, 23, 3), "Z2.376Y2");
|
|
1580
|
+
checkFormat("arrow(3,24,3) → 2.376Aa23 (Aa diagonal)", MetaNum.arrow(3, 24, 3), "2.376Aa23");
|
|
1581
|
+
checkFormat("arrow(3,100,3) → 2.376Aa99", MetaNum.arrow(3, 100, 3), "2.376Aa99");
|
|
1582
|
+
checkFormat("arrow(10,10000,10) → 1.000Aa10,000", MetaNum.arrow(10, 10000, 10), "2.000Aa10,000");
|
|
1583
|
+
checkFormat("nested arrow(3,arrow(3,100,3),3) → Aa2.376Aa99",
|
|
1584
|
+
MetaNum.arrow(3, MetaNum.arrow(3, 100, 3), 3), "Aa2.376Aa99");
|
|
1585
|
+
checkFormat("nested arrow(3,arrow(10,10000,10),3) → Aa1.000Aa10,000",
|
|
1586
|
+
MetaNum.arrow(3, MetaNum.arrow(10, 10000, 10), 3), "Aa2.000Aa10,000");
|
|
1587
|
+
// every display uses at most 2 distinct letter tokens (≤2-types rule)
|
|
1588
|
+
(function () {
|
|
1589
|
+
var cases = [
|
|
1590
|
+
MetaNum.arrow(3, 9, 3), MetaNum.arrow(4, 9, 4), MetaNum.arrow(5, 9, 5),
|
|
1591
|
+
MetaNum.arrow(3, 22, 3), MetaNum.arrow(3, 23, 3), MetaNum.arrow(3, 24, 3),
|
|
1592
|
+
MetaNum.arrow(3, 100, 3), MetaNum.arrow(10, 10000, 10),
|
|
1593
|
+
MetaNum.arrow(3, MetaNum.arrow(3, 100, 3), 3),
|
|
1594
|
+
];
|
|
1595
|
+
var all2 = true;
|
|
1596
|
+
for (var ci = 0; ci < cases.length; ci++) {
|
|
1597
|
+
var toks = (format(cases[ci]).match(/[A-Z][a-z]*/g) || []).filter(function (t) { return t !== "E"; });
|
|
1598
|
+
// strip the structural E inside numbers first, then count distinct tokens
|
|
1599
|
+
var s = format(cases[ci]).replace(/(\d(?:\.\d+)?)E[\d,]+/g, "$1");
|
|
1600
|
+
toks = (s.match(/[A-Z][a-z]*/g) || []);
|
|
1601
|
+
var seen = {};
|
|
1602
|
+
for (var ti = 0; ti < toks.length; ti++) seen[toks[ti]] = 1;
|
|
1603
|
+
if (Object.keys(seen).length > 2) { all2 = false; console.log(" >2 types:", format(cases[ci])); }
|
|
1604
|
+
}
|
|
1605
|
+
checkBool("all diagonal-cascade displays use ≤ 2 letter types", all2, true);
|
|
1606
|
+
})();
|
|
1607
|
+
|
|
1608
|
+
// ─────────────────────────────────────────────────────────────────
|
|
1609
|
+
// v2.0: rule 3 unification + pure dlsdl diagonal [2,10) convention
|
|
1610
|
+
// ─────────────────────────────────────────────────────────────────
|
|
1611
|
+
console.log("\n=== diagonal letter convention ===");
|
|
1612
|
+
// rule 3: n{λ}b = n{λ[b]}n
|
|
1613
|
+
checkBool("aper(3,5) = 3{5}3", MetaNum.aperiote(3,5).eq(MetaNum(3).arrow(5)(3)), true);
|
|
1614
|
+
// diagonal letters (ending in 'a'): integer arguments all anchor at 2.000
|
|
1615
|
+
[10, 11, 50, 100].forEach(function (b) {
|
|
1616
|
+
checkFormat("10{100}" + b + " → 2.000Aa100", MetaNum.arrow(10, 100, b), "2.000Aa100");
|
|
1617
|
+
});
|
|
1618
|
+
checkFormat("11{100}11 → 2.000Aa100", MetaNum.arrow(11, 100, 11), "2.000Aa100");
|
|
1619
|
+
// structured count climbs to its smooth diagonal mantissa
|
|
1620
|
+
checkFormat("10{100}(10{93}10) → 2.002Aa100",
|
|
1621
|
+
MetaNum.arrow(10, 100, MetaNum.arrow(10, 93, 10)), "2.002Aa100");
|
|
1622
|
+
// non-diagonal letters keep the [1,10) convention
|
|
1623
|
+
checkFormat("Ab100 → 1.000Ab100", MetaNum("Ab100"), "1.000Ab100");
|
|
1624
|
+
// symbol de-layering
|
|
1625
|
+
checkFormat("!Aa3 → 2.000Aaaa10", MetaNum("!Aa3"), "2.000Aaaa10");
|
|
1626
|
+
checkFormat("@Aa3 → !2.000Aaaa10", MetaNum("@Aa3"), "!2.000Aaaa10");
|
|
1627
|
+
// parser roundtrip of the new canonical forms
|
|
1628
|
+
checkBool("parse 2.000Aaaa10", MetaNum("2.000Aaaa10").format() === "2.000Aaaa10", true);
|
|
1629
|
+
checkBool("parse !2.000Aaaa10", MetaNum("!2.000Aaaa10").format() === "!2.000Aaaa10", true);
|
|
1630
|
+
checkBool("parse 2.002Aa100", MetaNum("2.002Aa100").format() === "2.002Aa100", true);
|
|
1631
|
+
// hardy(1e10+k) must not blow the stack
|
|
1632
|
+
(function () {
|
|
1633
|
+
var ok = true;
|
|
1634
|
+
for (var k = 0; k <= 60; k++) {
|
|
1635
|
+
try { MetaNum.hardy(1e10 + k); } catch (e) { ok = false; console.log("hardy threw at", 1e10 + k, e.message); }
|
|
1636
|
+
}
|
|
1637
|
+
checkBool("hardy(1e10+0..60) no throw", ok, true);
|
|
1638
|
+
})();
|
|
1639
|
+
// cross-config stability for the new cases
|
|
1640
|
+
(function () {
|
|
1641
|
+
var ref = null, stable = true;
|
|
1642
|
+
[10, 20, 50, 100].forEach(function (c) {
|
|
1643
|
+
MetaNum.maxRows = c; MetaNum.maxCols = c;
|
|
1644
|
+
var f = format(MetaNum.arrow(10, 100, MetaNum.arrow(10, 93, 10)));
|
|
1645
|
+
if (ref === null) ref = f;
|
|
1646
|
+
else if (f !== ref) { stable = false; console.log("cfg" + c + " drift: " + f + " vs " + ref); }
|
|
1647
|
+
});
|
|
1648
|
+
MetaNum.maxRows = 20; MetaNum.maxCols = 20;
|
|
1649
|
+
checkBool("v2.0: 10{100}(10{93}10) cross-config stable (" + ref + ")", stable, true);
|
|
1650
|
+
})();
|
|
1651
|
+
|
|
1652
|
+
// ─────────────────────────────────────
|
|
1653
|
+
// cross-config stability: identical formats at
|
|
1654
|
+
// maxRows = maxCols = 10 / 20 / 50 / 100 (±1 in the last shown digit)
|
|
1655
|
+
// ─────────────────────────────────────
|
|
1656
|
+
console.log("\n=== cross-config stability ===");
|
|
1657
|
+
(function () {
|
|
1658
|
+
var cases = [[3, 9, 3], [3, 10, 3], [4, 9, 4], [5, 9, 5], [6, 9, 6],
|
|
1659
|
+
[3, 22, 3], [3, 23, 3], [3, 24, 3], [3, 39, 3], [3, 100, 3],
|
|
1660
|
+
[10, 25, 10], [10, 10000, 10]];
|
|
1661
|
+
var cfgs = [10, 20, 50, 100];
|
|
1662
|
+
var stable = true;
|
|
1663
|
+
for (var i = 0; i < cases.length; i++) {
|
|
1664
|
+
var ref = null;
|
|
1665
|
+
for (var c = 0; c < cfgs.length; c++) {
|
|
1666
|
+
MetaNum.maxRows = cfgs[c]; MetaNum.maxCols = cfgs[c];
|
|
1667
|
+
var f = format(MetaNum.arrow(cases[i][0], cases[i][1], cases[i][2]));
|
|
1668
|
+
if (ref === null) ref = f;
|
|
1669
|
+
else if (f !== ref) {
|
|
1670
|
+
// allow ±1 in the last displayed digit
|
|
1671
|
+
var a = ref.match(/(\d+(?:\.\d+)?)(?!.*\d)/), b = f.match(/(\d+(?:\.\d+)?)(?!.*\d)/);
|
|
1672
|
+
if (!a || !b || Math.abs(Number(a[1]) - Number(b[1])) > 1.5 * Math.pow(10, -(a[1].split(".")[1] || "").length + 1)) {
|
|
1673
|
+
stable = false;
|
|
1674
|
+
console.log(" config drift [" + cases[i] + "] " + ref + " vs @" + cfgs[c] + " " + f);
|
|
1675
|
+
} else { ref = f; }
|
|
1676
|
+
}
|
|
1677
|
+
}
|
|
1678
|
+
}
|
|
1679
|
+
MetaNum.maxRows = 20; MetaNum.maxCols = 20;
|
|
1680
|
+
checkBool("formats identical across maxRows/maxCols = 10/20/50/100 (±1 last digit)", stable, true);
|
|
1681
|
+
// clamped bounds: values below 10 and above 1000 snap inside
|
|
1682
|
+
MetaNum.maxRows = 5; checkBool("maxRows clamps up to 10", MetaNum.maxRows === 10, true);
|
|
1683
|
+
MetaNum.maxRows = 5000; checkBool("maxRows clamps down to 1000", MetaNum.maxRows === 1000, true);
|
|
1684
|
+
MetaNum.maxRows = 20;
|
|
1685
|
+
})();
|
|
1686
|
+
|
|
1687
|
+
console.log("\n=== MetaNum(...).format() instance method ===");
|
|
1688
|
+
(function () {
|
|
1689
|
+
function checkFmtEq(name, gotStr, expected) {
|
|
1690
|
+
var pass = gotStr === expected;
|
|
1691
|
+
console.log((pass ? "PASS" : "FAIL") + " | " + name + " | " + gotStr
|
|
1692
|
+
+ (pass ? "" : " (expected " + expected + ")"));
|
|
1693
|
+
}
|
|
1694
|
+
checkFmtEq("G600.format()", MetaNum("G600").format(), "1.000G600");
|
|
1695
|
+
checkFmtEq("hardy(4166).format()", MetaNum.hardy(4166).format(), "2.397G5");
|
|
1696
|
+
checkFmtEq("arrow(3,4.1,3).format()", MetaNum.arrow(3, 4.1, 3).format(), "G1.161G897");
|
|
1697
|
+
checkFmtEq("small 0.5.format()", MetaNum(0.5).format(), "0.500");
|
|
1698
|
+
checkFmtEq("format(2) precision arg", MetaNum(1234.5678).format(2), "1,234");
|
|
1699
|
+
checkFmtEq(".format() matches module format(FE400)",
|
|
1700
|
+
MetaNum("FE400").format(), format(MetaNum("FE400")));
|
|
1701
|
+
})();
|
|
1702
|
+
|
|
1703
|
+
console.log("\n=== format tests Done ===");
|
|
1704
|
+
|
|
873
1705
|
|
|
874
|
-
console.log("\n=== format tests Done ===");
|