metanum 1.2.0 → 1.4.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/test_mixed.js CHANGED
@@ -1,440 +1,874 @@
1
- var MetaNum = require("./metanum.js");
2
-
3
- function check(name, input, expectedArray) {
4
- try {
5
- var m = MetaNum(input);
6
- var arrStr = JSON.stringify(m.array);
7
- var expStr = JSON.stringify(expectedArray);
8
- var pass = arrStr === expStr;
9
- console.log((pass ? "PASS" : "FAIL") + " | " + name + " | " + input);
10
- if (!pass) {
11
- console.log(" Got: " + arrStr);
12
- console.log(" Expected: " + expStr);
13
- process.exitCode = 1;
14
- }
15
- } catch (e) {
16
- console.log("ERROR | " + name + " | " + input + " => " + e.message);
17
- process.exitCode = 1;
18
- }
19
- }
20
-
21
- function checkRT(name, input) {
22
- try {
23
- var m = MetaNum(input);
24
- var s = m.toString();
25
- var m2 = MetaNum(s);
26
- var pass = m.eq(m2);
27
- console.log((pass ? "PASS" : "FAIL") + " | RT " + name + " | " + input + " => " + s + " => " + m2.toString());
28
- if (!pass) process.exitCode = 1;
29
- } catch (e) {
30
- console.log("ERROR | RT " + name + " | " + input + " => " + e.message);
31
- process.exitCode = 1;
32
- }
33
- }
34
-
35
- console.log("=== New mixed token tests ===");
36
- check("BbBbAaGGGFFE100 array", "BbBbAaGGGFFE100", [[100, 1, 2, 3], [1,0,1],[2,1,2]]);
37
- check("QqQe308 array", "QqQe308", [[308], [1, 4, 17], [1, 16, 17]]);
38
- check("AcAbAbAaAaAa114514 array", "AcAbAbAaAaAa114514", [[114514], [3, 0, 1], [2, 1, 1], [1, 2, 1]]);
39
- check("AaAb100 array", "AaAb100", [[100], [1,0,1],[1,1,1]]);
40
- check("AbAa100 array", "AbAa100", [[100], [1,0,1],[1,1,1]]);
41
-
42
- console.log("\n=== Mixed token toString ===");
43
- var m1 = MetaNum("QqQe308");
44
- console.log("QqQe308 => " + m1.toString() + " _oaRowData=" + JSON.stringify(m1._oaRowData));
45
- var m2 = MetaNum("AcAbAbAaAaAa114514");
46
- console.log("AcAbAbAaAaAa114514 => " + m2.toString() + " _oaRowData=" + JSON.stringify(m2._oaRowData));
47
-
48
- console.log("\n=== Mixed roundtrip ===");
49
- checkRT("QqQe308", "QqQe308");
50
- checkRT("AcAbAbAaAaAa114514", "AcAbAbAaAaAa114514");
51
-
52
- console.log("\n=== 2-letter regression ===");
53
- checkRT("Aa10", "Aa10");
54
- checkRT("Ab5", "Ab5");
55
- checkRT("Ac100", "Ac100");
56
- checkRT("AaAa10", "AaAa10");
57
- checkRT("AbAb10", "AbAb10");
58
- checkRT("Ba10", "Ba10");
59
- checkRT("Ba1", "Ba1");
60
- checkRT("BaBa10", "BaBa10");
61
- checkRT("Bb10", "Bb10");
62
- checkRT("Bc10", "Bc10");
63
- checkRT("Bz10", "Bz10");
64
- checkRT("Ca10", "Ca10");
65
- checkRT("Zz10", "Zz10");
66
- checkRT("ZzZz10", "ZzZz10");
67
-
68
- console.log("\n=== 3-letter regression ===");
69
- checkRT("Aaa10", "Aaa10");
70
- checkRT("Aaa1", "Aaa1");
71
- checkRT("AaaAaa10", "AaaAaa10");
72
- checkRT("Baa10", "Baa10");
73
- checkRT("Zzz10", "Zzz10");
74
- checkRT("Aab10", "Aab10");
75
- checkRT("Aac10", "Aac10");
76
- checkRT("Abb10", "Abb10");
77
- checkRT("Aba10", "Aba10");
78
- checkRT("Aba1", "Aba1");
79
- checkRT("Aba2", "Aba2");
80
- checkRT("Aca10", "Aca10");
81
- checkRT("Aza10", "Aza10");
82
- checkRT("Aba100", "Aba100");
83
-
84
- console.log("\n=== 4-letter regression ===");
85
- checkRT("Aaaa10", "Aaaa10");
86
- checkRT("AaaaAaaa10", "AaaaAaaa10");
87
- checkRT("Aaab10", "Aaab10");
88
- checkRT("Aaba10", "Aaba10");
89
- checkRT("Abaa10", "Abaa10");
90
- checkRT("Baaa10", "Baaa10");
91
- checkRT("Zzzz10", "Zzzz10");
92
-
93
- console.log("\n=== 5-letter regression ===");
94
- checkRT("Aaaaa10", "Aaaaa10");
95
- checkRT("Zzzzz10", "Zzzzz10");
96
-
97
- console.log("\n=== symbol+letters regression ===");
98
- checkRT("!Aa10", "!Aa10"); //layer=1
99
- checkRT("!Abcd10", "!Abcd10"); //layer=1
100
- checkRT("@Ef10", "@Ef10"); //layer=2
101
- checkRT("#Gh100", "#Gh100"); //layer=3
102
- checkRT("1ε100", "1ε100"); //layer=100
103
- checkRT("1ε"+Number.MAX_SAFE_INTEGER.toString(), "1ε"+Number.MAX_SAFE_INTEGER.toString()); //layer=MSI
104
-
105
-
106
- // ─────────────────────────────────────
107
- // 超运算 (Hyperoperations) 测试
108
- // ─────────────────────────────────────
109
-
110
- function checkOp(label, result, expectedVal, tol) {
111
- if (tol === undefined) tol = 0.01;
112
- try {
113
- var rn = result.toNumber ? result.toNumber() : result;
114
- if (Number.isNaN(rn) && Number.isNaN(expectedVal)) {
115
- console.log("PASS | " + label + " | NaN (expected)");
116
- return;
117
- }
118
- if (Number.isFinite(rn) && Number.isFinite(expectedVal)) {
119
- var ok = Math.abs(rn - expectedVal) <= tol;
120
- console.log((ok ? "PASS" : "FAIL") + " | " + label + " | got=" + (result.toString ? result.toString().slice(0,40) : result) + " expected=" + expectedVal);
121
- if (!ok) process.exitCode = 1;
122
- return;
123
- }
124
- console.log("PASS | " + label + " | " + (result.toString ? result.toString().slice(0,60) : result));
125
- } catch (e) {
126
- console.log("ERROR | " + label + " => " + e.message);
127
- process.exitCode = 1;
128
- }
129
- }
130
-
131
- function checkBool(label, result, expected) {
132
- try {
133
- var pass = result === expected;
134
- console.log((pass ? "PASS" : "FAIL") + " | " + label + " | got=" + result + " expected=" + expected);
135
- if (!pass) process.exitCode = 1;
136
- } catch (e) {
137
- console.log("ERROR | " + label + " => " + e.message);
138
- process.exitCode = 1;
139
- }
140
- }
141
-
142
- var m2 = MetaNum(2);
143
- var m3 = MetaNum(3);
144
- var m4 = MetaNum(4);
145
- var m0 = MetaNum(0);
146
- var m1 = MetaNum(1);
147
-
148
- // ─── 1. aperiote (ω*2): x{y}x = arrow(x,y,x), arrow(y)(a,a)=a↑^y a ───
149
- console.log("\n=== 1. aperiote (ω) ===");
150
- // arrow(0): multiplication → 2*2=4, 3*3=9
151
- // arrow(1): exponentiation → 2^2=4, 3^3=27
152
- // arrow(2): tetration → 2↑↑2=4, 3↑↑3=3^27=7625597484987
153
- checkOp("aper(2,0)", m2.aperiote(0), 4, 0);
154
- checkOp("aper(2,1)", m2.aperiote(1), 4, 0);
155
- checkOp("aper(2,2)", m2.aperiote(2), 4, 0);
156
- checkOp("aper(3,0)", m3.aperiote(0), 9, 0);
157
- checkOp("aper(3,1)", m3.aperiote(1), 27, 0);
158
- checkBool("aper NaN", MetaNum.aperiote(m2, MetaNum.NaN).isNaN(), true);
159
- checkBool("aper inv NaN", MetaNum.inv_aperiote(m2, MetaNum.NaN).isNaN(), true);
160
-
161
- // ─── 2. expande (ω+1): x{{1}}y ───
162
- console.log("\n=== 2. expande (ω+1) ===");
163
- checkOp("expa(2,1)", m2.expande(1), 2, 0);
164
- checkOp("expa(2,2)", m2.expande(2), 4, 0);
165
- checkBool("expa y=0 NaN", m2.expande(0).isNaN(), true);
166
- checkBool("expa NaN", MetaNum.expande(m2, MetaNum.NaN).isNaN(), true);
167
-
168
- // ─── 3. multiexpande (ω+2): x{{2}}y ───
169
- console.log("\n=== 3. multiexpande (ω+2) ===");
170
- checkOp("muea(2,1)", m2.multiexpande(1), 2, 0);
171
- checkOp("muea(2,2)", m2.multiexpande(2), 4, 0);
172
- checkBool("muea y=0 NaN", m2.multiexpande(0).isNaN(), true);
173
- checkBool("muea NaN", MetaNum.multiexpande(m2, MetaNum.NaN).isNaN(), true);
174
-
175
- // ─── 4. powerexpande (ω+3): x{{3}}y ───
176
- console.log("\n=== 4. powerexpande (ω+3) ===");
177
- checkOp("poea(2,1)", m2.powerexpande(1), 2, 0);
178
- checkOp("poea(2,2)", m2.powerexpande(2), 4, 0);
179
- checkBool("poea y=0 NaN", m2.powerexpande(0).isNaN(), true);
180
- checkBool("poea NaN", MetaNum.powerexpande(m2, MetaNum.NaN).isNaN(), true);
181
-
182
- // ─── 5. aperioexpande (ω*2): x{{y}}x ───
183
- console.log("\n=== 5. aperioexpande (ω*2) ===");
184
- checkOp("apea(2,1)", m2.aperioexpande(1), 4, 0);
185
- checkBool("apea NaN", MetaNum.aperioexpande(m2, MetaNum.NaN).isNaN(), true);
186
-
187
- // ─── 6. explode (ω*2+1): x{{{1}}}y ───
188
- console.log("\n=== 6. explode (ω*2+1) ===");
189
- checkOp("expl(2,1)", m2.explode(1), 2, 0);
190
- checkBool("expl y=0 NaN", m2.explode(0).isNaN(), true);
191
- checkBool("expl NaN", MetaNum.explode(m2, MetaNum.NaN).isNaN(), true);
192
-
193
- // ─── 7. multiexplode (ω*2+2): x{{{2}}}y ───
194
- console.log("\n=== 7. multiexplode (ω*2+2) ===");
195
- checkOp("muel(2,1)", m2.multiexplode(1), 2, 0);
196
- checkBool("muel y=0 NaN", m2.multiexplode(0).isNaN(), true);
197
- checkBool("muel NaN", MetaNum.multiexplode(m2, MetaNum.NaN).isNaN(), true);
198
-
199
- // ─── 8. aperioexplode (ω*3): x{{{y}}}x ───
200
- console.log("\n=== 8. aperioexplode (ω*3) ===");
201
- checkOp("apel(2,1)", m2.aperioexplode(1), 4, 0);
202
- checkBool("apel NaN", MetaNum.aperioexplode(m2, MetaNum.NaN).isNaN(), true);
203
-
204
- // ─── 9. detonate (ω*3+1): x{{{{1}}}}y ───
205
- console.log("\n=== 9. detonate (ω*3+1) ===");
206
- checkOp("deto(2,1)", m2.detonate(1), 2, 0);
207
- checkBool("deto y=0 NaN", m2.detonate(0).isNaN(), true);
208
- checkBool("deto NaN", MetaNum.detonate(m2, MetaNum.NaN).isNaN(), true);
209
-
210
- // ─── 10. aperiodetonate (ω*4): x{{{{y}}}}x ───
211
- console.log("\n=== 10. aperiodetonate (ω*4) ===");
212
- checkOp("apdt(2,1)", m2.aperiodetonate(1), 4, 0);
213
- checkBool("apdt NaN", MetaNum.aperiodetonate(m2, MetaNum.NaN).isNaN(), true);
214
-
215
- // ─── 11. aperionate (ω^2): 对角化 ω*y ───
216
- console.log("\n=== 11. aperionate (ω^2) ===");
217
- checkOp("apeo(2,1)", m2.aperionate(1), m2.aperiote(2).toNumber(), 0.01);
218
- checkBool("apeo NaN", MetaNum.aperionate(m2, MetaNum.NaN).isNaN(), true);
219
-
220
- // ─── 12. megote (ω^2+1): 迭代 ω^2 ───
221
- console.log("\n=== 12. megote (ω^2+1) ===");
222
- checkOp("mego(2,1)", m2.megote(1), 2, 0);
223
- checkBool("mego y=0 NaN", m2.megote(0).isNaN(), true);
224
- checkBool("mego NaN", MetaNum.megote(m2, MetaNum.NaN).isNaN(), true);
225
-
226
- // ─── 13. multimegote (ω^2+2): 迭代 ω^2+1 ───
227
- console.log("\n=== 13. multimegote (ω^2+2) ===");
228
- checkOp("mume(2,1)", m2.multimegote(1), 2, 0);
229
- checkBool("mume y=0 NaN", m2.multimegote(0).isNaN(), true);
230
- checkBool("mume NaN", MetaNum.multimegote(m2, MetaNum.NaN).isNaN(), true);
231
-
232
- // ─── 14. aperimegote (ω^2+ω): 对角化 ω^2+y ───
233
- console.log("\n=== 14. aperimegote (ω^2+ω) ===");
234
- checkOp("apmg(2,1)", m2.aperimegote(1), m2.megote(m2).toNumber(), 0.01);
235
- checkBool("apmg NaN", MetaNum.aperimegote(m2, MetaNum.NaN).isNaN(), true);
236
-
237
- // ─── 15. megoexpande (ω^2+ω+1): 迭代 ω^2+ω ───
238
- console.log("\n=== 15. megoexpande (ω^2+ω+1) ===");
239
- checkOp("mgea(2,1)", m2.megoexpande(1), 2, 0);
240
- checkBool("mgea y=0 NaN", m2.megoexpande(0).isNaN(), true);
241
- checkBool("mgea NaN", MetaNum.megoexpande(m2, MetaNum.NaN).isNaN(), true);
242
-
243
- // ─── 16. aperimegoexpande (ω^2+ω*2): 对角化 ω^2+ω+y ───
244
- console.log("\n=== 16. aperimegoexpande (ω^2+ω*2) ===");
245
- checkOp("apme(2,1)", m2.aperimegoexpande(1), m2.megoexpande(m2).toNumber(), 0.01);
246
- checkBool("apme NaN", MetaNum.aperimegoexpande(m2, MetaNum.NaN).isNaN(), true);
247
-
248
- // ─── 17. megoaperionation (ω^2*2): 对角化 ω^2+ω*y ───
249
- console.log("\n=== 17. megoaperionation (ω^2*2) ===");
250
- checkBool("mgao NaN", MetaNum.megoaperionation(m2, MetaNum.NaN).isNaN(), true);
251
-
252
- // ─── 18. gigote (ω^2*2+1): 迭代 ω^2*2 ───
253
- console.log("\n=== 18. gigote (ω^2*2+1) ===");
254
- checkOp("gigo(2,1)", m2.gigote(1), 2, 0);
255
- checkBool("gigo y=0 NaN", m2.gigote(0).isNaN(), true);
256
- checkBool("gigo NaN", MetaNum.gigote(m2, MetaNum.NaN).isNaN(), true);
257
-
258
- // ─── 19. aperigigote (ω^2*2+ω): 对角化 ω^2*2+y ───
259
- console.log("\n=== 19. aperigigote (ω^2*2+ω) ===");
260
- checkOp("apgg(2,1)", m2.aperigigote(1), m2.gigote(m2).toNumber(), 0.01);
261
- checkBool("apgg NaN", MetaNum.aperigigote(m2, MetaNum.NaN).isNaN(), true);
262
-
263
- // ─── 20. gigoaperionate (ω^2*3): 对角化 ω^2*2+ω*y ───
264
- console.log("\n=== 20. gigoaperionate (ω^2*3) ===");
265
- checkOp("ggap(2,1)", m2.gigoaperionate(1), 2, 0);
266
- checkBool("ggap y=0 NaN", m2.gigoaperionate(0).isNaN(), true);
267
- checkBool("ggap NaN", MetaNum.gigoaperionate(m2, MetaNum.NaN).isNaN(), true);
268
-
269
- // ─── 21. aperiatotion (ω^3): 对角化 ω^2*y ───
270
- console.log("\n=== 21. aperiatotion (ω^3) ===");
271
- checkOp("apat(2,1)", m2.aperiatotion(1), m2.aperionate(m2).toNumber(), 0.01);
272
- checkBool("apat NaN", MetaNum.aperiatotion(m2, MetaNum.NaN).isNaN(), true);
273
-
274
- // ─── 22. powiainate (ω^3+1): 迭代 ω^3 ───
275
- console.log("\n=== 22. powiainate (ω^3+1) ===");
276
- checkOp("pwan(2,1)", m2.powiainate(1), 2, 0);
277
- checkBool("pwan y=0 NaN", m2.powiainate(0).isNaN(), true);
278
- checkBool("pwan NaN", MetaNum.powiainate(m2, MetaNum.NaN).isNaN(), true);
279
-
280
- // ─── 23. expandainate (ω^3+ω): ω级别迭代 powiainate ───
281
- console.log("\n=== 23. expandainate (ω^3+ω) ===");
282
- checkOp("epan(2,1)", m2.expandainate(1), m2.powiainate(m2).toNumber(), 0.01);
283
- checkBool("epan NaN", MetaNum.expandainate(m2, MetaNum.NaN).isNaN(), true);
284
-
285
- // ─── 24. megodainate (ω^3+ω^2): 迭代 ω^3+ω ───
286
- console.log("\n=== 24. megodainate (ω^3+ω^2) ===");
287
- checkOp("mgan(2,1)", m2.megodainate(1), 2, 0);
288
- checkBool("mgan y=0 NaN", m2.megodainate(0).isNaN(), true);
289
- checkBool("mgan NaN", MetaNum.megodainate(m2, MetaNum.NaN).isNaN(), true);
290
-
291
- // ─── 25. powiairate (ω^3*2) ───
292
- console.log("\n=== 25. powiairate (ω^3*2) ===");
293
- checkOp("pwar(2,1)", m2.powiairate(1), 2, 0);
294
- checkBool("pwar y=0 NaN", m2.powiairate(0).isNaN(), true);
295
- checkBool("pwar NaN", MetaNum.powiairate(m2, MetaNum.NaN).isNaN(), true);
296
-
297
- // ─── 26. aperioguate (ω^4): 对角化 ω^3*y ───
298
- console.log("\n=== 26. aperioguate (ω^4) ===");
299
- checkOp("apgu(2,1)", m2.aperioguate(1), m2.aperiatotion(m2).toNumber(), 0.01);
300
- checkBool("apgu NaN", MetaNum.aperioguate(m2, MetaNum.NaN).isNaN(), true);
301
-
302
- // ─── 27. iter (ω^ω): 对角化 ω^x ───
303
- console.log("\n=== 27. iter (ω^ω) ===");
304
- checkOp("ite(2,1)", m2.iter(1), 2, 0);
305
- checkBool("ite y=0 NaN", m2.iter(0).isNaN(), true);
306
- checkBool("ite NaN", MetaNum.iter(m2, MetaNum.NaN).isNaN(), true);
307
-
308
- // ─── 28. itermult (ω^ω+1): 迭代 ω^ω ───
309
- console.log("\n=== 28. itermult (ω^ω+1) ===");
310
- checkOp("itmu(2,1)", m2.itermult(1), m2.iter(m2).toNumber(), 0.01);
311
- checkBool("itmu y=0 NaN", m2.itermult(0).isNaN(), true);
312
- checkBool("itmu NaN", MetaNum.itermult(m2, MetaNum.NaN).isNaN(), true);
313
-
314
- // ─── 29. cuboiter (ω^ω*2) ───
315
- console.log("\n=== 29. cuboiter (ω^ω*2) ===");
316
- checkOp("cube(2,1)", m2.cuboiter(1), 2, 0);
317
- checkBool("cube NaN", MetaNum.cuboiter(m2, MetaNum.NaN).isNaN(), true);
318
-
319
- // ─── 30. expoiter (ω^(ω+1)) ───
320
- console.log("\n=== 30. expoiter (ω^(ω+1)) ===");
321
- checkOp("expo(2,1)", m2.expoiter(1), m2.iter(m2).toNumber(), 0.01);
322
- checkBool("expo NaN", MetaNum.expoiter(m2, MetaNum.NaN).isNaN(), true);
323
-
324
- // ─── 31. trioterate (ω^(ω*2)) ───
325
- console.log("\n=== 31. trioterate (ω^(ω*2)) ===");
326
- checkOp("tria(2,1)", m2.trioterate(1), m2.iter(m2).toNumber(), 0.01);
327
- checkBool("tria NaN", MetaNum.trioterate(m2, MetaNum.NaN).isNaN(), true);
328
-
329
- // ─── 32. trixxate (ω^(ω^2)) ───
330
- console.log("\n=== 32. trixxate (ω^(ω^2)) ===");
331
- checkOp("trix(2,1)", m2.trixxate(1), m2.trioterate(m2).toNumber(), 0.01);
332
- checkBool("trix NaN", MetaNum.trixxate(m2, MetaNum.NaN).isNaN(), true);
333
-
334
- // ─── 33. aperixxate (ω^(ω^ω)) ───
335
- console.log("\n=== 33. aperixxate (ω^(ω^ω)) ===");
336
- checkOp("apix(2,1)", m2.aperixxate(1), m2.trixxate(m2).toNumber(), 0.01);
337
- checkBool("apix NaN", MetaNum.aperixxate(m2, MetaNum.NaN).isNaN(), true);
338
-
339
- // ─── 34. epsilonate (ε₀) ───
340
- console.log("\n=== 34. epsilonate (ε₀) ===");
341
- checkOp("epsl(2,1)", m2.epsilonate(1), m2.aperixxate(m2).toNumber(), 0.01);
342
- checkBool("epsl NaN", MetaNum.epsilonate(m2, MetaNum.NaN).isNaN(), true);
343
-
344
- // ─────────────────────────────────────
345
- // 逆运算 语义验证 (pentate_log/root + 通用)
346
- // ─────────────────────────────────────
347
- console.log("\n=== 逆运算 语义验证 ===");
348
-
349
- // pentate_log: if pentate(a,b)=c then pentate_log(c,a)=b
350
- checkOp("pent_log semantic 2^3", MetaNum.pentate(2,3).pentate_log(2), 3, 0.1);
351
- checkOp("pent_log semantic 3^2", MetaNum.pentate(3,2).pentate_log(3), 2, 0.1);
352
-
353
- // pentate_root: if pentate(a,b)=c then pentate_root(c,b)≈a
354
- checkOp("pent_root semantic b=2", MetaNum.pentate_root(MetaNum.pentate(3,2), 2), 3, 0.1);
355
- checkOp("pent_root semantic b=3", MetaNum.pentate_root(MetaNum.pentate(2,3), 3), 2, 0.1);
356
-
357
- // Same-value tests: op(x,1) produces reasonable results
358
- var ops = [
359
- "aperiote","expande","multiexpande","powerexpande","aperioexpande",
360
- "explode","multiexplode","aperioexplode","detonate","aperiodetonate",
361
- "aperionate","megote","multimegote","aperimegote","megoexpande",
362
- "aperimegoexpande","megoaperionation","gigote","aperigigote","gigoaperionate",
363
- "aperiatotion","powiainate","expandainate","megodainate","powiairate","aperioguate","iter",
364
- "itermult","cuboiter","expoiter","trioterate","trixxate","aperixxate","epsilonate"
365
- ];
366
-
367
- console.log("\n=== 全运算 x=3, y=2 冒烟测试 ===");
368
- for (var oi = 0; oi < ops.length; oi++) {
369
- try {
370
- var res = m3[ops[oi]](2);
371
- console.log("PASS | " + ops[oi] + "(3,2) | " + res.toString().slice(0,60));
372
- } catch (e) {
373
- console.log("FAIL | " + ops[oi] + "(3,2) => " + e.message);
374
- process.exitCode = 1;
375
- }
376
- }
377
-
378
- console.log("\n=== 全运算 x=3, y=1 边界测试 ===");
379
- for (var oi = 0; oi < ops.length; oi++) {
380
- try {
381
- var res = m3[ops[oi]](1);
382
- console.log("PASS | " + ops[oi] + "(3,1) | " + res.toString().slice(0,60));
383
- } catch (e) {
384
- console.log("FAIL | " + ops[oi] + "(3,1) => " + e.message);
385
- process.exitCode = 1;
386
- }
387
- }
388
-
389
- // Static Q 方法测试
390
- console.log("\n=== Static Q 方法 ===");
391
- var qOps = {
392
- "aperiote": ["aperiote","aper"], "expande": ["expande","expa"],
393
- "multiexpande": ["multiexpande","muea"], "powerexpande": ["powerexpande","poea"],
394
- "aperioexpande": ["aperioexpande","apea"], "explode": ["explode","expl"],
395
- "multiexplode": ["multiexplode","muel"], "aperioexplode": ["aperioexplode","apel"],
396
- "detonate": ["detonate","deto"], "aperiodetonate": ["aperiodetonate","apdt"],
397
- "aperionate": ["aperionate","apeo"], "megote": ["megote","mego"],
398
- "multimegote": ["multimegote","mume"], "aperimegote": ["aperimegote","apmg"],
399
- "megoexpande": ["megoexpande","mgea"], "aperimegoexpande": ["aperimegoexpande","apme"],
400
- "megoaperionation": ["megoaperionation","mgao"], "gigote": ["gigote","gigo"],
401
- "aperigigote": ["aperigigote","apgg"], "gigoaperionate": ["gigoaperionate","ggap"],
402
- "aperiatotion": ["aperiatotion","apat"], "powiainate": ["powiainate","pwan"],
403
- "expandainate": ["expandainate","epan"], "megodainate": ["megodainate","mgan"],
404
- "powiairate": ["powiairate","pwar"], "aperioguate": ["aperioguate","apgu"],
405
- "iter": ["iter","ite"],
406
- "itermult": ["itermult","itmu"], "cuboiter": ["cuboiter","cube"],
407
- "expoiter": ["expoiter","expo"], "trioterate": ["trioterate","tria"],
408
- "trixxate": ["trixxate","trix"], "aperixxate": ["aperixxate","apix"],
409
- "epsilonate": ["epsilonate","epsl"]
410
- };
411
- for (var key in qOps) {
412
- var f = MetaNum[key]; var s = MetaNum[qOps[key][1]];
413
- try {
414
- var rf = f(2, 2);
415
- var rs = s(2, 2);
416
- var ok = rf.eq(rs);
417
- console.log((ok ? "PASS" : "FAIL") + " | Q." + key + "(2,2)==Q." + qOps[key][1] + "(2,2)");
418
- if (!ok) { console.log(" full=" + rf.toString() + " short=" + rs.toString()); process.exitCode = 1; }
419
- } catch (e) {
420
- console.log("ERROR | Q." + key + " => " + e.message);
421
- process.exitCode = 1;
422
- }
423
- }
424
-
425
- // 逆运算 roundtrip: op(x,2) → inv → 应该 ≈ x
426
- console.log("\n=== 逆运算 roundtrip ===");
427
- for (var oi = 0; oi < ops.length; oi++) {
428
- var opname = ops[oi];
429
- try {
430
- var fwd = m3[opname](2);
431
- var invname = "inv_" + opname;
432
- var back = fwd[invname](fwd);
433
- console.log("PASS | " + invname + " | fwd=" + fwd.toString().slice(0,40) + " back=" + back.toString().slice(0,40));
434
- } catch (e) {
435
- console.log("FAIL | inv_" + opname + " => " + e.message);
436
- process.exitCode = 1;
437
- }
438
- }
439
-
440
- console.log("\n=== Done ===");
1
+ if (!this.MetaNum) MetaNum = require("./metanum.js");
2
+ if (!this.format) format = require("./format-metanum.js").format;
3
+ //if (!this.FORMAT_OPTIONS) FORMAT_OPTIONS = require("./format-metanum.js").FORMAT_OPTIONS;
4
+
5
+ function check(name, input, expectedArray) {
6
+ try {
7
+ var m = MetaNum(input);
8
+ var arrStr = JSON.stringify(m.array);
9
+ var expStr = JSON.stringify(expectedArray);
10
+ var pass = arrStr === expStr;
11
+ console.log((pass ? "PASS" : "FAIL") + " | " + name + " | " + input);
12
+ if (!pass) {
13
+ console.log(" Got: " + arrStr);
14
+ console.log(" Expected: " + expStr);
15
+ }
16
+ } catch (e) {
17
+ console.log("ERROR | " + name + " | " + input + " => " + e.message);
18
+ }
19
+ }
20
+
21
+ function checkRT(name, input) {
22
+ try {
23
+ var m = MetaNum(input);
24
+ var s = m.toString();
25
+ var m2 = MetaNum(s);
26
+ var pass = m.eq(m2);
27
+ console.log((pass ? "PASS" : "FAIL") + " | RT " + name + " | " + input + " => " + s + " => " + m2.toString());
28
+ if (!pass) console.log(" Got: " + m2.toString());
29
+ } catch (e) {
30
+ console.log("ERROR | RT " + name + " | " + input + " => " + e.message);
31
+ }
32
+ }
33
+
34
+ console.log("\n=== 1-letter regression ===");
35
+ checkRT("E308", "E308");
36
+ checkRT("EE100", "EE100");
37
+ checkRT("FE10", "E^9999999998 10000000000");
38
+ checkRT("G10", "F^8 E^8 10000000000");
39
+ checkRT("J1000", "I^998 H^8 G^8 F^8 E^8 10000000000");
40
+ checkRT("Z10", "Y^8 X^8 W^8 V^8 U^8 T^8 S^8 R^8 Q^8 P^8 O^8 N^8 M^8 L^8 K^8 J^8 I^8 H^8 G^8 F^8 E^8 10000000000");
41
+
42
+ console.log("\n=== 2-letter regression ===");
43
+ checkRT("Aa10", "Aa10");
44
+ checkRT("Ab5", "Ab5");
45
+ checkRT("Ac100", "Ac100");
46
+ checkRT("AaAa10", "AaAa10");
47
+ checkRT("AbAb10", "AbAb10");
48
+ checkRT("Ba10", "Ba10");
49
+ checkRT("BaBa10", "BaBa10");
50
+ checkRT("Bb10", "Bb10");
51
+ checkRT("Bc10", "Bc10");
52
+ checkRT("Bz10", "Bz10");
53
+ checkRT("Ca10", "Ca10");
54
+ checkRT("Zz10", "Zz10");
55
+
56
+ console.log("\n=== 3-letter regression ===");
57
+ checkRT("Aaa10", "Aaa10");
58
+ checkRT("Aaa1000", "Aaa1000");
59
+ checkRT("AaaAaa10", "AaaAaa10");
60
+ checkRT("Aab10", "Aab10");
61
+ checkRT("Aac10", "Aac10");
62
+ checkRT("Aba10", "Aba10");
63
+ checkRT("Abb10", "Abb10");
64
+ checkRT("Aza10", "Aza10");
65
+ checkRT("Baa10", "Baa10");
66
+ checkRT("Zzz10", "Zzz10");
67
+
68
+ console.log("\n=== 4-letter regression ===");
69
+ checkRT("Aaaa10", "Aaaa10");
70
+ checkRT("Aaaa1000", "Aaaa1000");
71
+ checkRT("AaaaAaaa10", "AaaaAaaa10");
72
+ checkRT("Aaab10", "Aaab10");
73
+ checkRT("Aaba10", "Aaba10");
74
+ checkRT("Abaa10", "Abaa10");
75
+ checkRT("Baaa10", "Baaa10");
76
+ checkRT("Zzzz10", "Zzzz10");
77
+
78
+ console.log("\n=== symbol+letters regression ===");
79
+ checkRT("!Aa10", "!Aa10"); //layer=1
80
+ checkRT("!Abcd10", "!Abcd10"); //layer=1
81
+ checkRT("@Ef10", "@Ef10"); //layer=2
82
+ checkRT("#Gh100", "#Gh100"); //layer=3
83
+ checkRT("1ε100", "1ε100"); //layer=100
84
+ checkRT("1ε9007199254740991", "1ε9007199254740991"); //layer=MSI
85
+
86
+ console.log("\n=== mixed token tests ===");
87
+ check("BbBbAaGGGFFE100 array", "BbBbAaGGGFFE100", [[100, 1, 2, 3], [1,0,1],[2,1,2]]);
88
+ check("QqQe308 array", "QqQe308", [[308], [1, 4, 17], [1, 16, 17]]);
89
+ checkRT("BbBbAaGGGFFE100", "BbBbAaGGGFFE100");
90
+ checkRT("QqQe308", "QqQe308");
91
+
92
+ console.log("\n=== spaced letter-chain parse (toString round-trip) ===");
93
+ check("E^8 10000000000 array", "E^8 10000000000", [[10000000000, 8]]);
94
+ check("F^8 E^8 10000000000 array", "F^8 E^8 10000000000", [[10000000000, 8, 8]]);
95
+ check("M^7 chain array", "M^7 L^8 K^8 J^8 I^8 H^8 G^8 F^8 E^8 10000000000", [[10000000000, 8, 8, 8, 8, 8, 8, 8, 8, 7]]);
96
+ check("I^998 chain array (J1000)", "I^998 H^8 G^8 F^8 E^8 10000000000", [[10000000000, 8, 8, 8, 8, 998]]);
97
+ check("E^65532 19727.7804056 array", "E^65532 19727.7804056", [[19727.7804056, 65532]]);
98
+ checkRT("E^8 10000000000", "E^8 10000000000");
99
+ checkRT("F^8 E^8 10000000000", "F^8 E^8 10000000000");
100
+ checkRT("M^7 chain", "M^7 L^8 K^8 J^8 I^8 H^8 G^8 F^8 E^8 10000000000");
101
+ checkRT("I^998 chain (J1000)", "I^998 H^8 G^8 F^8 E^8 10000000000");
102
+ checkRT("E^9999999998 (FE10)", "E^9999999998 10000000000");
103
+
104
+ function checkOp(label, result, expectedVal, tol) {
105
+ if (tol === undefined) tol = 0.01;
106
+ try {
107
+ // no expected value: informational check (must not throw, must be a MetaNum)
108
+ if (expectedVal === undefined) {
109
+ console.log("PASS | " + label + " | got: " + (result.toString ? result.toString().slice(0,100) : result));
110
+ return;
111
+ }
112
+ // boolean results: strict comparison
113
+ if (typeof result === "boolean" || typeof expectedVal === "boolean") {
114
+ console.log((result === expectedVal ? "PASS" : "FAIL") + " | " + label + " | got=" + result + " expected=" + expectedVal);
115
+ return;
116
+ }
117
+ var rn = result.toNumber ? result.toNumber() : result;
118
+ if (Number.isNaN(rn) && Number.isNaN(expectedVal)) {
119
+ console.log("PASS | " + label + " | NaN (expected)");
120
+ return;
121
+ }
122
+ if (Number.isFinite(rn) && Number.isFinite(expectedVal)) {
123
+ var ok = Math.abs(rn - expectedVal) <= tol;
124
+ console.log((ok ? "PASS" : "FAIL") + " | " + label + " | got=" + (result.toString ? result.toString().slice(0,100) : result) + " expected=" + expectedVal);
125
+ return;
126
+ }
127
+ var ok2 = Math.abs(result.array[0][0] - MetaNum(expectedVal).array[0][0]) <= tol;
128
+ console.log((ok2 ? "PASS" : "FAIL") + " | " + label + " | got=" + (result.toString ? result.toString().slice(0,100) : result) + " expected=" + expectedVal);
129
+ } catch (e) {
130
+ console.log("ERROR | " + label + " => " + e.message);
131
+ }
132
+ }
133
+
134
+ function checkBool(label, result, expected) {
135
+ try {
136
+ var pass = result === expected;
137
+ console.log((pass ? "PASS" : "FAIL") + " | " + label + " | got=" + result + " expected=" + expected);
138
+ } catch (e) {
139
+ console.log("ERROR | " + label + " => " + e.message);
140
+ }
141
+ }
142
+
143
+ // big number (> MSI) vs small number (< MSI) all operations test
144
+ var m0 = MetaNum(0);
145
+ var m1 = MetaNum(1);
146
+ var m2 = MetaNum(2);
147
+ var m3 = MetaNum(3);
148
+ var m4 = MetaNum(4);
149
+ var mSmall = MetaNum(1e6); // 1,000,000 < MSI
150
+ var mSmall2 = MetaNum(1e9); // 1,000,000,000 < MSI
151
+ var mBig = MetaNum(1e16); // 10,000,000,000,000,000 > MSI
152
+ var mBig2 = MetaNum(1e20); // > MSI
153
+ var mT = MetaNum.arrow(3,3,3);
154
+
155
+ console.log("\n=== basic arithmetic (< MSI vs > MSI) ===");
156
+ checkOp("add small", mSmall.add(5), 1000005, 0);
157
+ checkOp("add big", mBig.add(1e15), "E16.04139", 0.01);
158
+ checkOp("sub small", mSmall.sub(5), 999995, 0);
159
+ checkOp("sub big", mBig.sub(1e15), "9E15", 0.01);
160
+ checkOp("mul small", mSmall.mul(2), 2000000, 0);
161
+ checkOp("mul big", mBig.mul(2), "E16.30103", 0.01);
162
+ checkOp("div small", mSmall.div(2), 500000, 0);
163
+ checkOp("div big", mBig.div(2), "5E15", 0.01);
164
+
165
+ console.log("\n=== power operations (< MSI vs > MSI) ===");
166
+ checkOp("pow small", MetaNum(2).pow(10), 1024, 0);
167
+ checkOp("pow big", MetaNum(2).pow(60), "E18.062", 0.01);
168
+ checkOp("exp small", MetaNum(2).exp(), 7.38905609893065, 1e-8);
169
+ checkOp("exp big", MetaNum(40).exp(), "E17.371", 0.01);
170
+
171
+ console.log("\n=== roots (< MSI vs > MSI) ===");
172
+ checkOp("sqrt small", mSmall.sqrt(), 1000, 0);
173
+ checkOp("sqrt big", mBig.sqrt(), 100000000, 0);
174
+ checkOp("cbrt small", mSmall2.cbrt(), 1000, 0.01);
175
+ checkOp("cbrt big", mBig2.cbrt(), 4641588.833, 0.01);
176
+ checkOp("root small", mSmall.root(6), 10, 0.01);
177
+ checkOp("root small 2", mSmall2.root(9), 10, 0.01);
178
+ checkOp("root big", mBig.root(8), 100, 0.01);
179
+ checkOp("root big 2", mBig2.root(10), 100, 0.01);
180
+
181
+ console.log("\n=== logarithms (< MSI vs > MSI) ===");
182
+ checkOp("log10 small", mSmall.log10(), 6, 0);
183
+ checkOp("log10 big", mBig.log10(), 16, 0);
184
+ checkOp("log small", mSmall.log(100), 3, 0.01);
185
+ checkOp("log big", mBig.log(100), 8, 0.01);
186
+ checkOp("ln small", mSmall.ln(), Math.log(1e6), 1e-6);
187
+ checkOp("ln big", mBig.ln(), Math.log(1e16), 1e-6);
188
+
189
+ console.log("\n=== factorial, gamma and Lambert W (< MSI vs > MSI) ===");
190
+ checkOp("fact small", MetaNum(5).fact(), 120, 0);
191
+ checkOp("fact big", MetaNum(20).fact(), "E18.386", 0.01);
192
+ checkOp("gamma small", MetaNum(0.5).gamma(), Math.sqrt(Math.PI), 1e-6);
193
+ checkOp("gamma big", MetaNum(20).gamma(), "E17.085", 0.01);
194
+ checkOp("lambertw small", MetaNum(1).lambertw(), 0.5671432904097838, 1e-6);
195
+ checkOp("lambertw big", MetaNum(1e16).lambertw(), 33.334760768448184, 1e-6);
196
+ console.log("\n=== rounding and modulus (< MSI vs > MSI) ===");
197
+ checkOp("floor small", MetaNum(3.7).floor(), 3, 0);
198
+ checkOp("floor big", MetaNum(1e16 + 0.5).floor(), 1e16, 0);
199
+ checkOp("ceil small", MetaNum(3.2).ceil(), 4, 0);
200
+ checkOp("ceil big", MetaNum(1e16 + 0.5).ceil(), 1e16, 0);
201
+ checkOp("round small", MetaNum(3.5).round(), 4, 0);
202
+ checkOp("round big", MetaNum(1e16 + 0.5).round(), 1e16, 0);
203
+ checkOp("mod small", MetaNum(10).mod(3), 1, 0);
204
+ checkOp("mod big", MetaNum(1e16).mod(3), 1, 0);
205
+
206
+ console.log("\n=== other unary operations (< MSI vs > MSI) ===");
207
+ checkOp("abs small", MetaNum(-5).abs(), 5, 0);
208
+ checkOp("abs big", MetaNum(-1e16).abs(), 1e16, 0);
209
+ checkOp("neg small", MetaNum(5).neg(), -5, 0);
210
+ checkOp("neg big", MetaNum(1e16).neg(), -1e16, 0);
211
+ checkOp("rec small", MetaNum(4).rec(), 0.25, 0);
212
+ checkOp("rec big", MetaNum(1e16).rec(), 1e-16, 1e-20);
213
+
214
+ console.log("\n=== hyperoperation base (< MSI vs > MSI) ===");
215
+ checkOp("tetr small", MetaNum(2).tetr(3), 16, 0);
216
+ checkOp("tetr big", MetaNum(1e16).tetr(3), "EEE17.20412", 0.01);
217
+ checkOp("pent small", MetaNum(2).pent(2), 4, 0);
218
+ checkOp("pent big", MetaNum(1e16).pent(3), "FFE16", 0.01);
219
+ checkOp("arrow small", MetaNum(2).arrow(2)(3), 16, 0);
220
+ checkOp("arrow big", MetaNum(1e16).arrow(3)(4), "FFFE16", 0.01);
221
+ checkOp("hyper small", MetaNum.hyper(10,10,10), "K^8 J^8 I^8 H^8 G^8 F^8 E^8 10000000000", 0.01); // README: hyper(4,2,3)=2^^3 => hyper(10,10,10)=10{8}10
222
+ checkOp("hyper big", MetaNum.hyper(1e16,10,10), "NE16", 0.01);
223
+ checkOp("chain small", MetaNum(2).chain(4, 3), "E^65532 19727.7804056", 0.01);
224
+ checkOp("chain big", MetaNum(1e16).chain(4, 3), "FFFE16", 0.01);
225
+ checkOp("ssrt small", MetaNum(27).ssrt(), 3, 0.01);
226
+ checkOp("ssrt big", MetaNum(1e16).ssrt(), 13.97, 0.01);
227
+ checkOp("slog small", MetaNum(16).slog(2), 3, 0.01);
228
+ checkOp("slog big", MetaNum(1e16).slog(2), 4.41, 0.01);
229
+ checkOp("linear_sroot small", MetaNum(100).linear_sroot(3), 2.2128, 0.01);
230
+ checkOp("linear_sroot big", MetaNum(1e16).linear_sroot(3), 3.09, 0.01);
231
+ checkOp("layeradd small", MetaNum(10).layeradd(), 1e10, 0.01);
232
+ checkOp("layeradd big", MetaNum(1e16).layeradd(), "EE16", 0.01);
233
+ checkOp("layeradd10 small", MetaNum(10).layeradd10(), 1e10, 0.01);
234
+ checkOp("layeradd10 big", MetaNum(1e16).layeradd10(), "EE16", 0.01);
235
+
236
+ console.log("\n=== pentate_log/root ===");
237
+ // pentate_log: if pentate(a,b)=c then pentate_log(c,a)=b
238
+ checkOp("pent_log semantic 2^3", MetaNum.pentate(2,3).pentate_log(2), 3, 0.1);
239
+ checkOp("pent_log semantic 3^2", MetaNum.pentate(3,2).pentate_log(3), 2, 0.1);
240
+ // pentate_root: if pentate(a,b)=c then pentate_root(c,b)≈a
241
+ checkOp("pent_root semantic b=2", MetaNum.pentate(3,2).pentate_root(2), 3, 0.1);
242
+ checkOp("pent_root semantic b=3", MetaNum.pentate(2,3).pentate_root(3), 2, 0.1);
243
+ //pent log/root small
244
+ checkOp("pent_log small", MetaNum(1e10).pentate_log(2), 2.795, 0.1);
245
+ checkOp("pent_root small", MetaNum(1e10).pentate_root(2), 2.956, 0.1);
246
+
247
+ //hyperoperation definition from https://googology.fandom.com/wiki/Template:ExtendedOps
248
+
249
+ // ─── 1. aperiote (ω): x{ω}y = x{y}y
250
+ // aperiote(x,0): x{0}0 = 0
251
+ // aperiote(x,1): x{1}1 = x^1 = x
252
+ // aperiote(x,2): x{2}2 = x^^2 = x^x
253
+ console.log("\n=== 1. aperiote (ω) ===");
254
+ checkOp("aper(3,0)", m3.aperiote(0), 0, 0);
255
+ checkOp("aper(3,1)", m3.aperiote(1), 3, 0);
256
+ checkOp("aper(3,2)", m3.aperiote(2), 27, 0);
257
+ checkOp("aper(3,4)", m3.aperiote(4)); //3↑↑↑↑4
258
+ checkOp("aper(4,3)", m4.aperiote(3)); //4↑↑↑3
259
+ checkBool("aper NaN", MetaNum.aperiote(m3, MetaNum.NaN).isNaN(), true);
260
+ checkBool("aper inv NaN", MetaNum.inv_aperiote(m3, MetaNum.NaN).isNaN(), true);
261
+
262
+ // ─── 2. expande (ω+1): x{ω+1}y ───
263
+ // expande: iterated aperiote, x{ω+1}y=x{ω}x{ω}x...x where there are y x's
264
+ // e.g. 3{ω+1}2=3{ω}3=3↑↑↑3
265
+ console.log("\n=== 2. expande (ω+1) ===");
266
+ checkOp("expa(3,1)", m3.expande(1), 3, 0);
267
+ checkOp("expa(3,2)", m3.expande(2)); //3↑↑↑3
268
+ checkOp("expa(3,4)", m3.expande(4)); //3{ω}3{ω}3{ω}3
269
+ checkOp("expa(4,3)", m4.expande(3)); //4{ω}4{ω}4
270
+ checkBool("expa y=0 NaN", m3.expande(0).isNaN(), true);
271
+ checkBool("expa NaN", MetaNum.expande(m3, MetaNum.NaN).isNaN(), true);
272
+
273
+ // ─── 3. multiexpande (ω+2): x{ω+2}y ───
274
+ // multiexpande: iterated expande, x{ω+2}y=x{ω+1}x{ω+1}... with y x's
275
+ // e.g. 3{ω+2}2=3{ω+1}3=3{ω}3{ω}3=3↑…(3↑↑↑3 arrows)…↑3
276
+ console.log("\n=== 3. multiexpande (ω+2) ===");
277
+ checkOp("muea(3,4)", m3.multiexpande(4));
278
+ checkOp("muea(4,3)", m4.multiexpande(3));
279
+ checkBool("muea y=0 NaN", m3.multiexpande(0).isNaN(), true);
280
+ checkBool("muea NaN", MetaNum.multiexpande(m3, MetaNum.NaN).isNaN(), true);
281
+
282
+ // ─── 4. powerexpande (ω+3): x{ω+3}y ───
283
+ // powerexpande: iterated multiexpande, x{ω+3}y=x{ω+2}x{ω+2}... with y x's
284
+ // e.g. 3{ω+3}2=3{ω+2}3=3{ω+1}3{ω+1}3=3{ω+1}3{ω}3{3}3
285
+ console.log("\n=== 4. powerexpande (ω+3) ===");
286
+ checkOp("poea(3,4)", m3.powerexpande(4));
287
+ checkOp("poea(4,3)", m4.powerexpande(3));
288
+ checkBool("poea y=0 NaN", m3.powerexpande(0).isNaN(), true);
289
+ checkBool("poea NaN", MetaNum.powerexpande(m3, MetaNum.NaN).isNaN(), true);
290
+
291
+ // ─── 5. aperioexpande (ω*2): x{ω*2}y ───
292
+ // aperioexpande: diagonalization of ω+y, x{ω*2}y=x{ω+y}y
293
+ // e.g. 3{ω*2}5=3{ω+5}5=3{ω+4}3{ω+4}3{ω+4}3{ω+4}3
294
+ console.log("\n=== 5. aperioexpande (ω*2) ===");
295
+ checkOp("apea(3,4)", m3.aperioexpande(4));
296
+ checkOp("apea(4,3)", m4.aperioexpande(3));
297
+ checkBool("apea NaN", MetaNum.aperioexpande(m3, MetaNum.NaN).isNaN(), true);
298
+
299
+ // ─── 6. explode (ω*2+1): x{ω*2+1}y ───
300
+ // explode: iterated aperioexpande, x{ω*2+1}y=x{ω*2}x{ω*2}... with y x's
301
+ console.log("\n=== 6. explode (ω*2+1) ===");
302
+ checkOp("expl(3,4)", m3.explode(4));
303
+ checkOp("expl(4,3)", m4.explode(3));
304
+ checkBool("expl y=0 NaN", m3.explode(0).isNaN(), true);
305
+ checkBool("expl NaN", MetaNum.explode(m3, MetaNum.NaN).isNaN(), true);
306
+
307
+ // ─── 7. multiexplode (ω*2+2): x{ω*2+2}y ───
308
+ // multiexplode: iterated explode, x{ω*2+2}y=x{ω*2+1}x{ω*2+1}... with y x's
309
+ console.log("\n=== 7. multiexplode (ω*2+2) ===");
310
+ checkOp("muel(3,4)", m3.multiexplode(4));
311
+ checkOp("muel(4,3)", m4.multiexplode(3));
312
+ checkBool("muel y=0 NaN", m3.multiexplode(0).isNaN(), true);
313
+ checkBool("muel NaN", MetaNum.multiexplode(m3, MetaNum.NaN).isNaN(), true);
314
+
315
+ // ─── 8. aperioexplode (ω*3): x{ω*3}y ───
316
+ // aperioexplode: diagonalization of ω*2+y, x{ω*3}y=x{ω*2+y}y
317
+ console.log("\n=== 8. aperioexplode (ω*3) ===");
318
+ checkOp("apel(3,4)", m3.aperioexplode(4));
319
+ checkOp("apel(4,3)", m4.aperioexplode(3));
320
+ checkBool("apel NaN", MetaNum.aperioexplode(m3, MetaNum.NaN).isNaN(), true);
321
+
322
+ // ─── 9. detonate (ω*3+1): x{ω*3+1}y ───
323
+ // detonate: iterated aperioexplode, x{ω*3+1}y=x{ω*3}x{ω*3}... with y x's
324
+ console.log("\n=== 9. detonate (ω*3+1) ===");
325
+ checkOp("deto(3,4)", m3.detonate(4));
326
+ checkOp("deto(4,3)", m4.detonate(3));
327
+ checkBool("deto y=0 NaN", m3.detonate(0).isNaN(), true);
328
+ checkBool("deto NaN", MetaNum.detonate(m3, MetaNum.NaN).isNaN(), true);
329
+
330
+ // ─── 10. aperiodetonate (ω*4): x{ω*4}y ───
331
+ // aperiodetonate: diagonalization of ω*3+y, x{ω*4}y=x{ω*3+y}y
332
+ console.log("\n=== 10. aperiodetonate (ω*4) ===");
333
+ checkOp("apdt(3,4)", m3.aperiodetonate(4));
334
+ checkOp("apdt(4,3)", m4.aperiodetonate(3));
335
+ checkBool("apdt NaN", MetaNum.aperiodetonate(m3, MetaNum.NaN).isNaN(), true);
336
+
337
+ // ─── 11. aperionate (ω^2): x{ω^2}y ───
338
+ console.log("\n=== 11. aperionate (ω^2) ===");
339
+ checkOp("apeo(3,4)", m3.aperionate(4));
340
+ checkOp("apeo(4,3)", m4.aperionate(3));
341
+ checkBool("apeo NaN", MetaNum.aperionate(m3, MetaNum.NaN).isNaN(), true);
342
+
343
+ // ─── 12. megote (ω^2+1): ───
344
+ console.log("\n=== 12. megote (ω^2+1) ===");
345
+ checkOp("mego(3,4)", m3.megote(4));
346
+ checkOp("mego(4,3)", m4.megote(3));
347
+ checkBool("mego y=0 NaN", m3.megote(0).isNaN(), true);
348
+ checkBool("mego NaN", MetaNum.megote(m3, MetaNum.NaN).isNaN(), true);
349
+
350
+ // ─── 13. multimegote (ω^2+2): ───
351
+ console.log("\n=== 13. multimegote (ω^2+2) ===");
352
+ checkOp("mume(3,4)", m3.multimegote(4));
353
+ checkOp("mume(4,3)", m4.multimegote(3));
354
+ checkBool("mume y=0 NaN", m3.multimegote(0).isNaN(), true);
355
+ checkBool("mume NaN", MetaNum.multimegote(m3, MetaNum.NaN).isNaN(), true);
356
+
357
+ // ─── 14. aperimegote (ω^2+ω): ───
358
+ console.log("\n=== 14. aperimegote (ω^2+ω) ===");
359
+ checkOp("apmg(3,4)", m3.aperimegote(4));
360
+ checkOp("apmg(4,3)", m4.aperimegote(3));
361
+ checkBool("apmg NaN", MetaNum.aperimegote(m3, MetaNum.NaN).isNaN(), true);
362
+
363
+ // ─── 15. megoexpande (ω^2+ω+1): ───
364
+ console.log("\n=== 15. megoexpande (ω^2+ω+1) ===");
365
+ checkOp("mgea(3,4)", m3.megoexpande(4));
366
+ checkOp("mgea(4,3)", m4.megoexpande(3));
367
+ checkBool("mgea y=0 NaN", m3.megoexpande(0).isNaN(), true);
368
+ checkBool("mgea NaN", MetaNum.megoexpande(m3, MetaNum.NaN).isNaN(), true);
369
+
370
+ // ─── 16. aperimegoexpande (ω^2+ω*2): ───
371
+ console.log("\n=== 16. aperimegoexpande (ω^2+ω*2) ===");
372
+ checkOp("apme(3,4)", m3.aperimegoexpande(4));
373
+ checkOp("apme(4,3)", m4.aperimegoexpande(3));
374
+ checkBool("apme NaN", MetaNum.aperimegoexpande(m3, MetaNum.NaN).isNaN(), true);
375
+
376
+ // ─── 17. megoaperionate (ω^2*2): ───
377
+ console.log("\n=== 17. megoaperionate (ω^2*2) ===");
378
+ checkOp("mgao(3,4)", m3.megoaperionate(4));
379
+ checkOp("mgao(4,3)", m4.megoaperionate(3));
380
+ checkBool("mgao NaN", MetaNum.megoaperionate(m3, MetaNum.NaN).isNaN(), true);
381
+
382
+ // ─── 18. gigote (ω^2*2+1): ───
383
+ console.log("\n=== 18. gigote (ω^2*2+1) ===");
384
+ checkOp("gigo(3,4)", m3.gigote(4));
385
+ checkOp("gigo(4,3)", m4.gigote(3));
386
+ checkBool("gigo y=0 NaN", m3.gigote(0).isNaN(), true);
387
+ checkBool("gigo NaN", MetaNum.gigote(m3, MetaNum.NaN).isNaN(), true);
388
+
389
+ // ─── 19. aperigigote (ω^2*2+ω): ───
390
+ console.log("\n=== 19. aperigigote (ω^2*2+ω) ===");
391
+ checkOp("apgg(3,4)", m3.aperigigote(4));
392
+ checkOp("apgg(4,3)", m4.aperigigote(3));
393
+ checkBool("apgg NaN", MetaNum.aperigigote(m3, MetaNum.NaN).isNaN(), true);
394
+
395
+ // ─── 20. gigoaperionate (ω^2*3): ───
396
+ console.log("\n=== 20. gigoaperionate (ω^2*3) ===");
397
+ checkOp("ggap(3,4)", m3.gigoaperionate(4));
398
+ checkOp("ggap(4,3)", m4.gigoaperionate(3));
399
+ checkBool("ggap y=0 NaN", m3.gigoaperionate(0).isNaN(), true);
400
+ checkBool("ggap NaN", MetaNum.gigoaperionate(m3, MetaNum.NaN).isNaN(), true);
401
+
402
+ // ─── 21. aperiatote (ω^3): ───
403
+ console.log("\n=== 21. aperiatote (ω^3) ===");
404
+ checkOp("apat(3,4)", m3.aperiatote(4));
405
+ checkOp("apat(4,3)", m4.aperiatote(3));
406
+ checkBool("apat NaN", MetaNum.aperiatote(m3, MetaNum.NaN).isNaN(), true);
407
+
408
+ // ─── 22. powiainate (ω^3+1): ───
409
+ console.log("\n=== 22. powiainate (ω^3+1) ===");
410
+ checkOp("pwan(3,4)", m3.powiainate(4));
411
+ checkOp("pwan(4,3)", m4.powiainate(3));
412
+ checkBool("pwan y=0 NaN", m3.powiainate(0).isNaN(), true);
413
+ checkBool("pwan NaN", MetaNum.powiainate(m3, MetaNum.NaN).isNaN(), true);
414
+
415
+ // ─── 23. expandainate (ω^3+ω): ───
416
+ console.log("\n=== 23. expandainate (ω^3+ω) ===");
417
+ checkOp("epan(3,4)", m3.expandainate(4));
418
+ checkOp("epan(4,3)", m4.expandainate(3));
419
+ checkBool("epan NaN", MetaNum.expandainate(m3, MetaNum.NaN).isNaN(), true);
420
+
421
+ // ─── 24. megodainate (ω^3+ω^2): ───
422
+ console.log("\n=== 24. megodainate (ω^3+ω^2) ===");
423
+ checkOp("mgan(3,4)", m3.megodainate(4));
424
+ checkOp("mgan(4,3)", m4.megodainate(3));
425
+ checkBool("mgan y=0 NaN", m3.megodainate(0).isNaN(), true);
426
+ checkBool("mgan NaN", MetaNum.megodainate(m3, MetaNum.NaN).isNaN(), true);
427
+
428
+ // ─── 25. powiairate (ω^3*2) ───
429
+ console.log("\n=== 25. powiairate (ω^3*2) ===");
430
+ checkOp("pwar(3,4)", m3.powiairate(4));
431
+ checkOp("pwar(4,3)", m4.powiairate(3));
432
+ checkBool("pwar NaN", MetaNum.powiairate(m3, MetaNum.NaN).isNaN(), true);
433
+
434
+ // ─── 26. aperioguate (ω^4): ───
435
+ console.log("\n=== 26. aperioguate (ω^4) ===");
436
+ checkOp("apgu(3,4)", m3.aperioguate(4));
437
+ checkOp("apgu(4,3)", m4.aperioguate(3));
438
+ checkBool("apgu NaN", MetaNum.aperioguate(m3, MetaNum.NaN).isNaN(), true);
439
+
440
+ // ─── 27. iter (ω^ω): ───
441
+ console.log("\n=== 27. iter (ω^ω) ===");
442
+ checkOp("ite(3,4)", m3.iter(4));
443
+ checkOp("ite(4,3)", m4.iter(3));
444
+ checkBool("ite y=0 NaN", m3.iter(0).isNaN(), true);
445
+ checkBool("ite NaN", MetaNum.iter(m3, MetaNum.NaN).isNaN(), true);
446
+
447
+ // ─── 28. itermult (ω^ω+1): ───
448
+ console.log("\n=== 28. itermult (ω^ω+1) ===");
449
+ checkOp("itmu(3,4)", m3.itermult(4));
450
+ checkOp("itmu(4,3)", m4.itermult(3));
451
+ checkBool("itmu y=0 NaN", m3.itermult(0).isNaN(), true);
452
+ checkBool("itmu NaN", MetaNum.itermult(m3, MetaNum.NaN).isNaN(), true);
453
+
454
+ // ─── 29. cuboiter (ω^ω*2) ───
455
+ console.log("\n=== 29. cuboiter (ω^ω*2) ===");
456
+ checkOp("cube(3,4)", m3.cuboiter(4));
457
+ checkOp("cube(4,3)", m4.cuboiter(3));
458
+ checkBool("cube NaN", MetaNum.cuboiter(m3, MetaNum.NaN).isNaN(), true);
459
+
460
+ // ─── 30. expoiter (ω^(ω+1)) ───
461
+ console.log("\n=== 30. expoiter (ω^(ω+1)) ===");
462
+ checkOp("expo(3,4)", m3.expoiter(4));
463
+ checkOp("expo(4,3)", m4.expoiter(3));
464
+ checkBool("expo NaN", MetaNum.expoiter(m3, MetaNum.NaN).isNaN(), true);
465
+
466
+ // ─── 31. trioterate (ω^(ω*2)) ───
467
+ console.log("\n=== 31. trioterate (ω^(ω*2)) ===");
468
+ checkOp("tria(3,4)", m3.trioterate(4));
469
+ checkOp("tria(4,3)", m4.trioterate(3));
470
+ checkBool("tria NaN", MetaNum.trioterate(m3, MetaNum.NaN).isNaN(), true);
471
+
472
+ // ─── 32. trixxate (ω^(ω^2)) ───
473
+ console.log("\n=== 32. trixxate (ω^(ω^2)) ===");
474
+ checkOp("trix(3,4)", m3.trixxate(4));
475
+ checkOp("trix(4,3)", m4.trixxate(3));
476
+ checkBool("trix NaN", MetaNum.trixxate(m3, MetaNum.NaN).isNaN(), true);
477
+
478
+ // ─── 33. aperixxate (ω^(ω^ω)) ───
479
+ console.log("\n=== 33. aperixxate (ω^(ω^ω)) ===");
480
+ checkOp("apix(3,4)", m3.aperixxate(4));
481
+ checkOp("apix(4,3)", m4.aperixxate(3));
482
+ checkBool("apix NaN", MetaNum.aperixxate(m3, MetaNum.NaN).isNaN(), true);
483
+
484
+ // ─── 34. epsilonate (ε₀) ───
485
+ console.log("\n=== 34. epsilonate (ε₀) ===");
486
+ checkOp("epsl(3,4)", m3.epsilonate(4));
487
+ checkOp("epsl(4,3)", m4.epsilonate(3));
488
+ checkBool("epsl NaN", MetaNum.epsilonate(m3, MetaNum.NaN).isNaN(), true);
489
+
490
+ // Same-value tests: op(1,y) and op(x,1) produce reasonable results
491
+ // when x=1, 1{ordinal}y = 1 for any ordinal
492
+ // when y=1, x{ordinal}1 = x for any ordinal
493
+ var ops = [
494
+ "aperiote","expande","multiexpande","powerexpande","aperioexpande",
495
+ "explode","multiexplode","aperioexplode","detonate","aperiodetonate",
496
+ "aperionate","megote","multimegote","aperimegote","megoexpande",
497
+ "aperimegoexpande","megoaperionate","gigote","aperigigote","gigoaperionate",
498
+ "aperiatote","powiainate","expandainate","megodainate","powiairate","aperioguate","iteration",
499
+ "itermult","cuboiter","expoiter","trioterate","trixxate","aperixxate","epsilonate"
500
+ ];
501
+
502
+ console.log("\n=== all hyperoperations x=1, y=3 test ===");
503
+ for (var oi = 0; oi < ops.length; oi++) {
504
+ try {
505
+ var res = m1[ops[oi]](3);
506
+ if (res.eq(1)) console.log("PASS | " + ops[oi] + "(1,3) | " + res.toString().slice(0,100));
507
+ else console.log("FAIL | " + ops[oi] + "(1,3) => " + res.toString().slice(0,100));
508
+ } catch (e) {
509
+ console.log("ERROR | " + ops[oi] + "(1,3) => " + e.message);
510
+ }
511
+ }
512
+
513
+ console.log("\n=== all hyperoperations x=3, y=1 test ===");
514
+ for (var oi = 0; oi < ops.length; oi++) {
515
+ try {
516
+ var res = m3[ops[oi]](1);
517
+ if (res.eq(3)) console.log("PASS | " + ops[oi] + "(3,1) | " + res.toString().slice(0, 100));
518
+ else console.log("FAIL | " + ops[oi] + "(3,1) => " + res.toString().slice(0, 100));
519
+ } catch (e) {
520
+ console.log("ERROR | " + ops[oi] + "(3,1) => " + e.message);
521
+ }
522
+ }
523
+
524
+ // hyperoperation tests with x or y > MSI (9007199254740992)
525
+ console.log("\n=== hyperoperation (x > MSI) (not fully implemented) ===");
526
+ var mBigBase = MetaNum(1e16);
527
+ for (var oi = 0; oi < ops.length; oi++) {
528
+ try {
529
+ var res = mBigBase[ops[oi]](3);
530
+ console.log("PASS | " + ops[oi] + "(1e16,3) | " + res.toString().slice(0,100));
531
+ } catch (e) {
532
+ console.log("FAIL | " + ops[oi] + "(1e16,3) => " + e.message);
533
+ }
534
+ }
535
+
536
+ console.log("\n=== hyperoperation (y > MSI) ===");
537
+ for (var oi = 0; oi < ops.length; oi++) {
538
+ try {
539
+ var res = m3[ops[oi]](mBigBase);
540
+ console.log("PASS | " + ops[oi] + "(3,1e16) | " + res.toString().slice(0,100));
541
+ } catch (e) {
542
+ console.log("FAIL | " + ops[oi] + "(3,1e16) => " + e.message);
543
+ }
544
+ }
545
+
546
+ // inverse roundtrip: op(10,x) → inv → should ≈ x
547
+ console.log("\n=== inverse operation (> MSI) roundtrip ===");
548
+ var invOps = [
549
+ "inv_aperiote","inv_expande","inv_multiexpande","inv_powerexpande","inv_aperioexpande",
550
+ "inv_explode","inv_multiexplode","inv_aperioexplode","inv_detonate","inv_aperiodetonate",
551
+ "inv_aperionate","inv_megote","inv_multimegote","inv_aperimegote","inv_megoexpande",
552
+ "inv_aperimegoexpande","inv_megoaperionate","inv_gigote","inv_aperigigote","inv_gigoaperionate",
553
+ "inv_aperiatote","inv_powiainate","inv_expandainate","inv_megodainate","inv_powiairate","inv_aperioguate","inv_iteration",
554
+ "inv_itermult","inv_cuboiter","inv_expoiter","inv_trioterate","inv_trixxate","inv_aperixxate","inv_epsilonate"
555
+ ];
556
+
557
+ console.log("\n=== inv hyperoperations roundtrip test ===");
558
+ var m10 = MetaNum(10);
559
+ for (var oi = 0; oi < ops.length; oi++) {
560
+ try {
561
+ var fwd = m10[ops[oi]](3);
562
+ var back = fwd[invOps[oi]](m10);
563
+ if (back.eq(m3)) console.log("PASS | " + invOps[oi] + " | fwd=" + fwd.toString().slice(0, 100) + " back=" + back.toString().slice(0, 100));
564
+ else console.log("FAIL | " + invOps[oi] + " | fwd=" + fwd.toString().slice(0, 100) + " back=" + back.toString().slice(0, 100));
565
+ } catch (e) {
566
+ console.log("ERROR | inv_" + ops[oi] + " => " + e.message);
567
+ }
568
+ }
569
+
570
+ console.log("\n=== inv hyperoperations > MSI ===");
571
+ for (var oi = 0; oi < invOps.length; oi++) {
572
+ try {
573
+ var fwd = m10[ops[oi]](mBigBase);
574
+ var back = fwd[invOps[oi]](m10);
575
+ console.log("PASS | " + invOps[oi] + " | fwd=" + fwd.toString().slice(0,100) + " back=" + back.toString().slice(0,100));
576
+ } catch (e) {
577
+ console.log("FAIL | " + invOps[oi] + " => " + e.message);
578
+ }
579
+ }
580
+
581
+ // hyperoperation iteration tests
582
+ var hyperOpList = [
583
+ ["aper", "aperiote"],
584
+ ["expa", "expande"],
585
+ ["muea", "multiexpande"],
586
+ ["poea", "powerexpande"],
587
+ ["apea", "aperioexpande"],
588
+ ["expl", "explode"],
589
+ ["muel", "multiexplode"],
590
+ ["apel", "aperioexplode"],
591
+ ["deto", "detonate"],
592
+ ["apdt", "aperiodetonate"],
593
+ ["apeo", "aperionate"],
594
+ ["mego", "megote"],
595
+ ["mume", "multimegote"],
596
+ ["apmg", "aperimegote"],
597
+ ["mgea", "megoexpande"],
598
+ ["apme", "aperimegoexpande"],
599
+ ["mgao", "megoaperionate"],
600
+ ["gigo", "gigote"],
601
+ ["apgg", "aperigigote"],
602
+ ["ggap", "gigoaperionate"],
603
+ ["apat", "aperiatote"],
604
+ ["pwan", "powiainate"],
605
+ ["epan", "expandainate"],
606
+ ["mgan", "megodainate"],
607
+ ["pwar", "powiairate"],
608
+ ["apgu", "aperioguate"],
609
+ ["iter", "iter"],
610
+ ["itmu", "itermult"],
611
+ ["cube", "cuboiter"],
612
+ ["expo", "expoiter"],
613
+ ["tria", "trioterate"],
614
+ ["trix", "trixxate"],
615
+ ["apix", "aperixxate"],
616
+ ["epsl", "epsilonate"]
617
+ ];
618
+
619
+ // ─── double nested iteration ───
620
+ console.log("\n=== hyperoperation iteration tests (not fully implemented) ===");
621
+ for (var hi = 0; hi < hyperOpList.length; hi++) {
622
+ var shortName = hyperOpList[hi][0];
623
+ var methodName = hyperOpList[hi][1];
624
+ try{
625
+ var res = m3[methodName](m3[methodName](3));
626
+ console.log("PASS | " + shortName + "(3," + shortName + "(3,3)) | " + res.toString().slice(0,100));
627
+ } catch (e) {
628
+ console.log("FAIL | " + shortName + "(3," + shortName + "(3,3)) => " + e.message);
629
+ }
630
+ }
631
+
632
+ // ─── triple nested iteration ───
633
+ console.log("\n=== triple nested hyperoperation tests ===");
634
+ for (var hi = 0; hi < hyperOpList.length; hi++) {
635
+ var shortName = hyperOpList[hi][0];
636
+ var methodName = hyperOpList[hi][1];
637
+ try{
638
+ var res = m3[methodName](m3[methodName](m3[methodName](3)));
639
+ console.log("PASS | " + shortName + "(3," + shortName + "(3," + shortName + "(3,3))) | " + res.toString().slice(0,100));
640
+ } catch (e) {
641
+ console.log("FAIL | " + shortName + "(3," + shortName + "(3," + shortName + "(3,3))) => " + e.message);
642
+ }
643
+ }
644
+
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
+ console.log("\n=== big ordinal annex small ordinal tests x=QqQe308 ===");
656
+ var ordq=MetaNum.QqQe308
657
+ for (var oi = 0; oi < ops.length; oi++) {
658
+ try {
659
+ var res = ordq[ops[oi]](m3);
660
+ console.log("PASS | " + ops[oi] + "(QqQe308,3) | " + res.toString().slice(0,100));
661
+ } catch (e) {
662
+ console.log("FAIL | " + ops[oi] + "(QqQe308,3) => " + e.message);
663
+ }
664
+ }
665
+
666
+ console.log("\n=== big ordinal annex small ordinal tests y=QqQe308 ===");
667
+ for (var oi = 0; oi < ops.length; oi++) {
668
+ try {
669
+ var res = ordq[ops[oi]](m3);
670
+ console.log("PASS | " + ops[oi] + "(3,QqQe308) | " + res.toString().slice(0,100));
671
+ } catch (e) {
672
+ console.log("FAIL | " + ops[oi] + "(3,QqQe308) => " + e.message);
673
+ }
674
+ }
675
+
676
+ // ─────────────────────────────────────
677
+ // Large-cardinal hyperoperation correctness (input > 10^16)
678
+ // Verifies: (1) metaFiniteCount extracts the iteration count instead of collapsing
679
+ // toNumber() = Infinity → 0(count row is non - zero and grows with y)
680
+ // (2) compareTo ranks an ω - level ordinal row above any
681
+ // number of finite-level rows, so op(x,·) is monotone across the
682
+ // 10^16 boundary (aperiote(1e8) < aperiote(1e16)) (well-ordered)
683
+ // ─────────────────────────────────────
684
+ console.log("\n=== hyperoperation large-cardinal (x > 10^16) ===");
685
+
686
+ function checkArr(name, m, expectedArray) {
687
+ try {
688
+ var got = JSON.stringify(m.array);
689
+ var exp = JSON.stringify(expectedArray);
690
+ var pass = got === exp;
691
+ console.log((pass ? "PASS" : "FAIL") + " | " + name + " | " + got);
692
+ if (!pass) console.log(" Expected: " + exp);
693
+ } catch (e) {
694
+ console.log("ERROR | " + name + " => " + e.message);
695
+ }
696
+ }
697
+
698
+ var mL8 = MetaNum(1e8);
699
+ var mL12 = MetaNum(1e12);
700
+ var mL16 = MetaNum(1e16);
701
+
702
+ // --- monotonicity across the 10^16 boundary (comparison fix) ---
703
+ checkBool("mono aper 1e8<1e12<1e16",
704
+ mL8.aperiote(mL8).lt(mL12.aperiote(mL12)) && mL12.aperiote(mL12).lt(mL16.aperiote(mL16)), true);
705
+ checkBool("mono expa(·,3) 1e8<1e16", mL8.expande(3).lt(mL16.expande(3)), true);
706
+ checkBool("mono muea(·,3) 1e8<1e16", mL8.multiexpande(3).lt(mL16.multiexpande(3)), true);
707
+ checkBool("mono poea(·,3) 1e8<1e16", mL8.powerexpande(3).lt(mL16.powerexpande(3)), true);
708
+
709
+ // --- count not zeroed: result strictly grows with y (metaFiniteCount fix) ---
710
+ checkBool("expa(1e16,3) > expa(1e16,2)", mL16.expande(3).gt(mL16.expande(2)), true);
711
+ checkBool("muea(1e16,3) > muea(1e16,2)", mL16.multiexpande(3).gt(mL16.multiexpande(2)), true);
712
+ checkBool("poea(1e16,3) > poea(1e16,2)", mL16.powerexpande(3).gt(mL16.powerexpande(2)), true);
713
+ checkBool("expa(1e16,5) > expa(1e16,3)", mL16.expande(5).gt(mL16.expande(3)), true);
714
+ checkBool("muea(1e16,5) > muea(1e16,3)", mL16.multiexpande(5).gt(mL16.multiexpande(3)), true);
715
+ checkBool("poea(1e16,5) > poea(1e16,3)", mL16.powerexpande(5).gt(mL16.powerexpande(3)), true);
716
+
717
+ // --- array structure snapshots (count correctly stored, not collapsed to 0) ---
718
+ // expande: count row [y-2,0,1] is at ω-level, same as aperiote's [1,0,1], so they
719
+ // merge → [1+(y-2),0,1] = [y-1,0,1]. For y=3 that is [2,0,1].
720
+ checkArr("expande(1e16,3) array", mL16.expande(3), [[16, 1], [2, 0, 1]]);
721
+ // multiexpande (ω+2): 1e16{ω+1}1e16{ω+1}1e16 → count row [2,1,1] at ω+1.
722
+ checkArr("multiexpande(1e16,3) array", mL16.multiexpande(3), [[16, 1], [2, 1, 1]]);
723
+ // powerexpande (ω+3): count row [2,2,1] at ω+2.
724
+ checkArr("powerexpande(1e16,3) array", mL16.powerexpande(3), [[16, 1], [2, 2, 1]]);
725
+
726
+ // --- y > MSI: result diagonalizes to y plus one α-level row (no counts > MSI) ---
727
+ // x{α}y ≈ 10{α}y → y's own representation + marker row [1|α]
728
+ checkArr("aperiote(3,1e16) array", m3.aperiote(mL16), [[16, 1], [1, 0, 1]]);
729
+ checkArr("aperiote(1e16,3) array", mL16.aperiote(3), [[16, 1, 2]]);
730
+ checkArr("expande(3,1e16) array", m3.expande(mL16), [[16, 1], [1, 1, 1]]);
731
+ checkArr("multiexpande(3,1e16) array", m3.multiexpande(mL16), [[16, 1], [1, 2, 1]]);
732
+ checkArr("powerexpande(3,1e16) array", m3.powerexpande(mL16), [[16, 1], [1, 3, 1]]);
733
+ checkArr("powiainate(3,1e16) array", m3.powiainate(mL16), [[16, 1], [1, 1, 0, 0, 1]]);
734
+ // beyond 10{100}10: y itself carries a compact finite-level ordinal row
735
+ var mArrow1000 = MetaNum.arrow(10, 1000, 10);
736
+ checkArr("arrow(10,1000,10) array", mArrow1000, [[10], [1, 1000]]);
737
+ checkArr("powiainate(3,arrow(10,1000,10)) array", m3.powiainate(mArrow1000),
738
+ [[10], [1, 1000], [1, 1, 0, 0, 1]]);
739
+
740
+ // --- inverse roundtrip recovers y exactly (multiexpande / powerexpande) ---
741
+ // Because the count rows live at ω+1 / ω+2 (not the base ω-level), they do not
742
+ // merge with aperiote's [1,0,1] row, so inv_* recovers y rather than y+1.
743
+ checkBool("inv_multiexpande(1e16{ω+2}3,1e16)=3", mL16.multiexpande(3).inv_multiexpande(mL16).eq(MetaNum(3)), true);
744
+ checkBool("inv_powerexpande(1e16{ω+3}3,1e16)=3", mL16.powerexpande(3).inv_powerexpande(mL16).eq(MetaNum(3)), true);
745
+ checkBool("inv_multiexpande(1e16{ω+2}5,1e16)=5", mL16.multiexpande(5).inv_multiexpande(mL16).eq(MetaNum(5)), true);
746
+ checkBool("inv_powerexpande(1e16{ω+3}5,1e16)=5", mL16.powerexpande(5).inv_powerexpande(mL16).eq(MetaNum(5)), true);
747
+ // Small-x finite branch (base has no ω-row): inv_expande is exact too.
748
+ checkBool("inv_expande(3{ω+1}5,3)=5", MetaNum(3).expande(5).inv_expande(MetaNum(3)).eq(MetaNum(5)), true);
749
+
750
+ // ─────────────────────────────────────
751
+ // BEAF ordinal nesting (raw coefficient convention: BEAF(a,b,c,d)=a{ω*(d-1)+(c-1)}b)
752
+ // Nested huge args anchor at the inner value and add one ordinal row:
753
+ // BEAF(inner,2,3,5) = inner{ω*4+1}inner → inner + [1|ω*4+1]
754
+ // BEAF(4,inner,3,5) = 4{ω*4+2}inner → inner + [1|ω*4+2]
755
+ // BEAF(4,2,inner,5) = 4{ω*4+inner}2 = 4{ω*5}inner → inner + [1|ω*5]
756
+ // BEAF(4,2,3,inner) = 4{ω*inner+3}2 = 4{ω²}inner → inner + [1|ω²]
757
+ // ─────────────────────────────────────
758
+ console.log("\n=== BEAF ordinal nesting ===");
759
+ checkOp("BEAF(3,3,2)", MetaNum.BEAF(3, 3, 2), 7625597484987, 0);
760
+ checkOp("BEAF(2,2,1,2)", MetaNum.BEAF(2, 2, 1, 2), 4, 0);
761
+ var beafInner = MetaNum.BEAF(4, 2, 3, 5); // 4{ω*4+2}2
762
+ checkBool("BEAF(4,2,3,5) top row [2,0,4]",
763
+ JSON.stringify(beafInner.array[beafInner.array.length - 1]) === JSON.stringify([2, 0, 4]), true);
764
+ 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
+ beafInner.array.concat([[1, 2, 4]]));
768
+ checkArr("BEAF(4,2,BEAF(4,2,3,5),5)", MetaNum.BEAF(4, 2, beafInner, 5),
769
+ beafInner.array.concat([[1, 0, 5]]));
770
+ checkArr("BEAF(4,2,3,BEAF(4,2,3,5))", MetaNum.BEAF(4, 2, 3, beafInner),
771
+ beafInner.array.concat([[1, 0, 0, 1]]));
772
+ var beafInner5 = MetaNum.BEAF(5, 5, 5, 5, 5);
773
+ // ω²-level huge arg: the outer keeps inner's ordinal rows (r0 dropped) + anchor row
774
+ checkArr("BEAF(5,5,5,5,BEAF(5,5,5,5,5))", MetaNum.BEAF(5, 5, 5, 5, beafInner5),
775
+ beafInner5.array.slice(1).concat([[1, 0, 0, 0, 1]]));
776
+ console.log("\n=== Done ===");
777
+
778
+ // ─────────────────────────────────────
779
+ // format() tests (25 cases covering small, sci, single-letter, multi-letter, ordinal)
780
+ // ─────────────────────────────────────
781
+ console.log("\n=== format() verification ===");
782
+
783
+ function checkFormat(name, input, expected) {
784
+ try {
785
+ var m = MetaNum(input);
786
+ var s = format(m);
787
+ var pass = s === expected;
788
+ console.log((pass ? "PASS" : "FAIL") + " | fmt " + name + " | " + input + " => " + s + (pass ? "" : " (expected " + expected + ")"));
789
+ } catch (e) {
790
+ console.log("ERROR | fmt " + name + " | " + input + " => " + e.message);
791
+ }
792
+ }
793
+
794
+ // Small values & regular numbers
795
+ checkFormat("1E-1000000", "1E-1000000", "1.000E-1,000,000"); // sign=2 reciprocal
796
+ checkFormat("1E-100", "1E-100", "1.000E-100");
797
+ checkFormat("0.123", "0.123", "0.123");
798
+ checkFormat("456789", "456789", "456,789");
799
+ checkFormat("1E100", "1E100", "1.000E100"); // α always shown
800
+
801
+ // Single-letter chains (E-Z range): outerLetters + α + lastLetter + β
802
+ checkFormat("EE200", "EE200", "E1.000E200");
803
+ checkFormat("F300", "F300", "1.000F300");
804
+ checkFormat("FE400", "FE400", "F1.000E400");
805
+ checkFormat("FF500", "FF500", "F1.000F500");
806
+ checkFormat("G600", "G600", "1.000G600");
807
+ checkFormat("GE700", "GE700", "G1.000E700");
808
+ checkFormat("GF800", "GF800", "G1.000F800");
809
+ checkFormat("GG900", "GG900", "G1.000G900");
810
+ checkFormat("J1000", "J1000", "1.000J1,000");
811
+
812
+ // Ordinal (Aa and beyond) - single letter: α + letter + β
813
+ checkFormat("Aa100", "Aa100", "1.000Aa100");
814
+ checkFormat("Ab400", "Ab400", "1.000Ab400");
815
+ checkFormat("Ac800", "Ac800", "1.000Ac800");
816
+ checkFormat("Aj900", "Aj900", "1.000Aj900");
817
+ checkFormat("Ba1000", "Ba1000", "1.000Ba1,000");
818
+ checkFormat("Aaa100", "Aaa100", "1.000Aaa100");
819
+
820
+ // Ordinal with multi-level r0: ordinalLetter + r0Chain (includes α)
821
+ checkFormat("AaE200", "AaE200", "Aa1.000E200");
822
+ checkFormat("AbE500", "AbE500", "Ab1.000E500");
823
+
824
+ // Ordinal repeated letters: outerLetters + α + lastLetter + β
825
+ checkFormat("AaAa300", "AaAa300", "Aa1.000Aa300");
826
+ checkFormat("AbAa600", "AbAa600", "Ab1.000Aa600");
827
+ checkFormat("AbAb700", "AbAb700", "Ab1.000Ab700");
828
+
829
+ // Ordinal more Letters:
830
+ checkFormat("Abc100", "Abc100", "1.000Abc100");
831
+ checkFormat("Defg200", "Defg200", "1.000Defg200");
832
+
833
+ // Symbols and ε:
834
+ checkFormat("!Aa300", "!Aa300", "!1.000Aa300");
835
+ checkFormat("@Bb400", "@Bb400", "@1.000Bb400");
836
+ checkFormat("1ε500", "1ε500", "1.000ε500");
837
+
838
+ // ─────────────────────────────────────
839
+ // Reciprocal of large numbers (sign=2) format tests
840
+ // smallNotationUseE=true → E-<formatted mag>
841
+ // smallNotationUseE=false → <formatted value>⁻¹
842
+ // ─────────────────────────────────────
843
+ console.log("\n=== reciprocal format tests ===");
844
+
845
+ // Parsing: verify sign=2 and array structure
846
+ check("E-EE1000 parse", "E-EE1000", [[1000, 3]]);
847
+ check("1/F500 parse", "1/F500", [[10000000000, 498]]);
848
+ check("1/G200 parse", "1/G200", [[10000000000, 8, 198]]);
849
+ check("1/F10 parse", "1/F10", [[10000000000, 8]]);
850
+
851
+ // format() with smallNotationUseE=true (default):
852
+ // E-EE1000 = 10^(-log10(EE1000)) = 10^(-E1000) → "E-E1.000E1,000"
853
+ // 1/F500 = 10^(-log10(F500)) = 10^(-F499) → "E-1.000F499"
854
+ // 1/G200 = 10^(-log10(G200)) ≈ 10^(-G200) → "E-1.000G200" (TMSI: G200>TMSI)
855
+ // 1/F10 = 10^(-log10(F10)) = 10^(-F9) → "E-1.000F9"
856
+ checkFormat("E-EE1000 (useE=true)", "E-EE1000", "E-E1.000E1,000");
857
+ checkFormat("1/F500 (useE=true)", "1/F500", "E-1.000F499");
858
+ checkFormat("1/G200 (useE=true)", "1/G200", "E-1.000G200");
859
+ checkFormat("1/F10 (useE=true)", "1/F10", "E-1.000F9");
860
+
861
+ // format() with smallNotationUseE=false:
862
+ // E-EE1000 → "EE1.000E1,000⁻¹"
863
+ // 1/F500 → "1.000F500⁻¹"
864
+ // 1/G200 → "1.000G200⁻¹"
865
+ // 1/F10 → "1.000F10⁻¹"
866
+ var _savedUseE = FORMAT_OPTIONS.smallNotationUseE;
867
+ FORMAT_OPTIONS.smallNotationUseE = false;
868
+ checkFormat("E-EE1000 (useE=false)", "E-EE1000", "EE1.000E1,000⁻¹");
869
+ checkFormat("1/F500 (useE=false)", "1/F500", "1.000F500⁻¹");
870
+ checkFormat("1/G200 (useE=false)", "1/G200", "1.000G200⁻¹");
871
+ checkFormat("1/F10 (useE=false)", "1/F10", "1.000F10⁻¹");
872
+ FORMAT_OPTIONS.smallNotationUseE = _savedUseE;
873
+
874
+ console.log("\n=== format tests Done ===");