metanum 2.0.2 → 2.0.3
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/format-metanum.js +21 -1
- package/metanum.js +219 -30
- package/package.json +1 -1
package/format-metanum.js
CHANGED
|
@@ -8,7 +8,7 @@ let FORMAT_DEBUG = 0
|
|
|
8
8
|
// ─── Configuration Options ────────────────────────────────────────
|
|
9
9
|
const FORMAT_OPTIONS = {
|
|
10
10
|
smallNotationUseE: true, //true/false
|
|
11
|
-
smallNotationThreshold:
|
|
11
|
+
smallNotationThreshold: 3, //0~9
|
|
12
12
|
decimalPlaces: 3, //0~9
|
|
13
13
|
decimalThreshold: 3, //0~15
|
|
14
14
|
useCommas: true, //true/false
|
|
@@ -645,6 +645,26 @@ function format(num, precision=3, small=false) {
|
|
|
645
645
|
if (num.sign < 0) return "-" + format(num.neg(), precision, small)
|
|
646
646
|
if (num.isInfinite()) return "Infinity"
|
|
647
647
|
|
|
648
|
+
// Sub-unit values (sign 2 / -2, the whole 0 < |v| < 1 range): a plain
|
|
649
|
+
// finite r0 stores the RECIPROCAL, so the real value is 1/r0 — format that
|
|
650
|
+
// number and let the normal machinery below render it (decimal places at or
|
|
651
|
+
// above 10^-smallNotationThreshold, αE-β below it). Reading the raw r0 as
|
|
652
|
+
// the value printed the reciprocal instead: MetaNum(1).div(2000)
|
|
653
|
+
// (r0 = [2000], value 5e-4) came out as "2.000E-3" instead of "5.000E-4".
|
|
654
|
+
// Structured sign-2 forms (layer > 0, ordinal rows, power-tower r0) keep the
|
|
655
|
+
// letter-law path further down.
|
|
656
|
+
if ((num.sign === 2 || num.sign === -2) && num.layer === 0 &&
|
|
657
|
+
num.array.length === 1 && num.array[0].length === 1 &&
|
|
658
|
+
isFinite(num.array[0][0]) && num.array[0][0] !== 0) {
|
|
659
|
+
let realVal = 1 / num.array[0][0]
|
|
660
|
+
if (isFinite(realVal) && realVal > 0) {
|
|
661
|
+
let asNormal = num.clone()
|
|
662
|
+
asNormal.sign = 1
|
|
663
|
+
asNormal.array = [[realVal]]
|
|
664
|
+
num = asNormal
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
|
|
648
668
|
// Small value handling (e.g., 0.0000000001 → 1.000E-10 or 1.000E10⁻¹)
|
|
649
669
|
let smallThreshold = Math.pow(10, -FORMAT_OPTIONS.smallNotationThreshold)
|
|
650
670
|
if (num.lt(smallThreshold)) {
|
package/metanum.js
CHANGED
|
@@ -228,6 +228,38 @@
|
|
|
228
228
|
return Math.log10(Number(str.substring(0, LONG_STRING_MIN_LENGTH))) + (str.length - LONG_STRING_MIN_LENGTH);
|
|
229
229
|
};
|
|
230
230
|
|
|
231
|
+
// Canonical form of a value with 0 < |v| < 1: the library stores it as the
|
|
232
|
+
// RECIPROCAL with sign 2 (0<v<1) / -2 (-1<v<0) — the same encoding the
|
|
233
|
+
// underflow path below already produced, now applied to the WHOLE sub-unit
|
|
234
|
+
// range so that `MetaNum(0.5).sign === 2` and every operation result in that
|
|
235
|
+
// range carries it too (README: sign 2 / -2 == 0~1 / -1~0).
|
|
236
|
+
//
|
|
237
|
+
// _skipCanon lets rec() produce the reciprocal of a sub-unit value (2 for 0.5)
|
|
238
|
+
// without this rule turning it straight back into a small value.
|
|
239
|
+
var _skipCanon = 0;
|
|
240
|
+
function canonicalizeSubUnit(x) {
|
|
241
|
+
if (_skipCanon) return x;
|
|
242
|
+
if (x.layer !== 0 || x.array.length !== 1) return x;
|
|
243
|
+
var r = x.array[0];
|
|
244
|
+
if (x.sign !== 1 && x.sign !== -1) return x; // already reciprocal-encoded
|
|
245
|
+
if (r.length === 1) {
|
|
246
|
+
var v = r[0];
|
|
247
|
+
if (!(typeof v === 'number') || !isFinite(v) || v <= 0 || v >= 1) return x;
|
|
248
|
+
r[0] = 1 / v;
|
|
249
|
+
x.sign = x.sign === -1 ? -2 : 2;
|
|
250
|
+
return x;
|
|
251
|
+
}
|
|
252
|
+
if (r.length === 2 && r[1] === 1) {
|
|
253
|
+
// 10^e with a negative exponent is sub-unit: store 10^(-e) as reciprocal
|
|
254
|
+
var e = r[0];
|
|
255
|
+
if (!(typeof e === 'number') || !isFinite(e) || e >= 0) return x;
|
|
256
|
+
r[0] = -e;
|
|
257
|
+
x.sign = x.sign === -1 ? -2 : 2;
|
|
258
|
+
return x;
|
|
259
|
+
}
|
|
260
|
+
return x;
|
|
261
|
+
}
|
|
262
|
+
|
|
231
263
|
P.normalize = function () {
|
|
232
264
|
var b;
|
|
233
265
|
var x = this;
|
|
@@ -469,6 +501,40 @@
|
|
|
469
501
|
return x;
|
|
470
502
|
};
|
|
471
503
|
|
|
504
|
+
// Apply the sub-unit canonical form to a public result (constructor input or
|
|
505
|
+
// the result of a basic arithmetic op). Deliberately NOT part of normalize():
|
|
506
|
+
// normalize runs on every internal intermediate, and the engine's own
|
|
507
|
+
// transcendentals (log10 → 0.301, slog, gamma, hyper-op levels) plus hardy's
|
|
508
|
+
// coefficient arrays read r0 structurally, so canonicalizing there broke
|
|
509
|
+
// them. See canonicalizeSubUnit above.
|
|
510
|
+
function canonicalizeResult(x) {
|
|
511
|
+
if (x instanceof MetaNum) canonicalizeSubUnit(x);
|
|
512
|
+
return x;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
// Constructor that never applies the sub-unit canonical form. Engine
|
|
516
|
+
// internals build values that are consumed STRUCTURALLY (r0 read as a
|
|
517
|
+
// magnitude, sign tested for -1): the transcendentals' own results
|
|
518
|
+
// (log10(2) = 0.301, slog, gamma, pent_log) and hardy's fractional
|
|
519
|
+
// coefficients. Canonicalizing those changed r0[0] from 0.301 to 3.32 and
|
|
520
|
+
// silently corrupted every consumer.
|
|
521
|
+
function rawMetaNum(v) {
|
|
522
|
+
_skipCanon++;
|
|
523
|
+
try { return new MetaNum(v); } finally { _skipCanon--; }
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
// Run fn with the sub-unit canonical form suppressed. Applied to the engine
|
|
527
|
+
// functions that CONSUME sub-unit magnitudes structurally (gamma's series,
|
|
528
|
+
// slog's log10 chain, the layeradd/pentate inverse paths): they read r0 as a
|
|
529
|
+
// plain magnitude, so a canonicalized intermediate (log10(2) → r0 [3.32]
|
|
530
|
+
// instead of [0.301]) silently produced garbage. The PRODUCERS (log10, ln,
|
|
531
|
+
// exp, root, the constructor, add/sub/mul/div) stay canonicalized, so the
|
|
532
|
+
// public contract the user asked for still holds.
|
|
533
|
+
function rawBody(fn, self, args) {
|
|
534
|
+
_skipCanon++;
|
|
535
|
+
try { return fn.apply(self, args || []); } finally { _skipCanon--; }
|
|
536
|
+
}
|
|
537
|
+
|
|
472
538
|
var standardizeMessageSent = false;
|
|
473
539
|
P.standardize = function () {
|
|
474
540
|
if (!standardizeMessageSent) console.warn(metaNumError + "'standardize' method is being deprecated in favor of 'normalize' and will be removed in the future!"), standardizeMessageSent = true;
|
|
@@ -501,6 +567,19 @@
|
|
|
501
567
|
if (this.array[0] && isNaN(this.array[0][0])) return NaN;
|
|
502
568
|
if (other.array[0] && isNaN(other.array[0][0])) return NaN;
|
|
503
569
|
|
|
570
|
+
// Plain finite numerics (any sign, including the sub-unit encoding 2/-2)
|
|
571
|
+
// compare as real numbers. The structural path below reads r0 as the
|
|
572
|
+
// magnitude and only inverts at the very end, so a sign-2 value like 0.2
|
|
573
|
+
// (stored as r0 = [5]) used to compare as 5 — every `lt`/`gt`/`eq` against a
|
|
574
|
+
// sub-unit value was wrong.
|
|
575
|
+
var tNum = plainNumericValue(this);
|
|
576
|
+
var oNum = plainNumericValue(other);
|
|
577
|
+
if (tNum !== null && oNum !== null) {
|
|
578
|
+
if (tNum < oNum) return -1;
|
|
579
|
+
if (tNum > oNum) return 1;
|
|
580
|
+
return 0;
|
|
581
|
+
}
|
|
582
|
+
|
|
504
583
|
var tInf = this.array[0] && this.array[0][0] === Infinity;
|
|
505
584
|
var oInf = other.array[0] && other.array[0][0] === Infinity;
|
|
506
585
|
|
|
@@ -796,6 +875,30 @@
|
|
|
796
875
|
return x.sign === 2 || x.sign === -2;
|
|
797
876
|
}
|
|
798
877
|
|
|
878
|
+
// The plain r0 magnitude as the engine's own numeric routines expect it:
|
|
879
|
+
// for a sub-unit value (sign 2/-2) r0 holds the RECIPROCAL, so unwrap it.
|
|
880
|
+
// Use this wherever a function does `isSimple(x) ? x.array[0][0] : …` to feed
|
|
881
|
+
// a float routine — otherwise 0.5 (r0 [2]) is read as 2.
|
|
882
|
+
function magnitudeOf(x) {
|
|
883
|
+
if (!isSmall(x)) return x.array[0][0];
|
|
884
|
+
return 1 / x.array[0][0];
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
// Real value of a plain finite numeric MetaNum, or null when the value is
|
|
888
|
+
// structured (layer > 0, ordinal rows, E/power-tower r0) and must go through
|
|
889
|
+
// the structural comparison. sign 2/-2 is the sub-unit encoding: r0 holds
|
|
890
|
+
// the reciprocal, so the value is 1/r0 (negated for -2).
|
|
891
|
+
function plainNumericValue(x) {
|
|
892
|
+
if (x.layer !== 0 || x.array.length !== 1) return null;
|
|
893
|
+
var r0 = x.array[0];
|
|
894
|
+
if (r0.length !== 1) return null;
|
|
895
|
+
var v = r0[0];
|
|
896
|
+
if (typeof v !== 'number' || !isFinite(v) || v === 0) return null;
|
|
897
|
+
if (x.sign === 2) return 1 / v;
|
|
898
|
+
if (x.sign === -2) return -1 / v;
|
|
899
|
+
return x.sign === -1 ? -v : v;
|
|
900
|
+
}
|
|
901
|
+
|
|
799
902
|
function isNumeric(x) {
|
|
800
903
|
return x.layer === 0 && x.array.length === 1 &&
|
|
801
904
|
x.array[0].length === 1 && isFinite(x.array[0][0]);
|
|
@@ -1011,9 +1114,11 @@
|
|
|
1011
1114
|
var domMul = layerDominant(x, other);
|
|
1012
1115
|
if (domMul !== null) return domMul.clone().normalize();
|
|
1013
1116
|
|
|
1014
|
-
if (isSimple(x) && isSimple(other)
|
|
1015
|
-
|
|
1016
|
-
|
|
1117
|
+
if (isSimple(x) && isSimple(other)) {
|
|
1118
|
+
// magnitudeOf: sub-unit operands (sign 2/-2) store the reciprocal, so
|
|
1119
|
+
// read the real values — otherwise 0.5·0.5 multiplied 2·2 = 4.
|
|
1120
|
+
var nx = magnitudeOf(x);
|
|
1121
|
+
var ny = magnitudeOf(other);
|
|
1017
1122
|
var n = nx * ny;
|
|
1018
1123
|
if (isFinite(n) && n !== 0 && Math.abs(n) <= MAX_SAFE_INTEGER) {
|
|
1019
1124
|
if (Math.abs(n) < 1) return new MetaNum(1 / Math.abs(n)).rec();
|
|
@@ -1066,9 +1171,11 @@
|
|
|
1066
1171
|
}
|
|
1067
1172
|
|
|
1068
1173
|
if (x.eq(MetaNum.ZERO)) return MetaNum.ZERO.clone();
|
|
1069
|
-
if (isSimple(x) && isSimple(other)
|
|
1070
|
-
|
|
1071
|
-
|
|
1174
|
+
if (isSimple(x) && isSimple(other)) {
|
|
1175
|
+
// magnitudeOf: sub-unit operands store the reciprocal — 0.5 / 0.25 must
|
|
1176
|
+
// read 0.5 and 0.25, not 2 and 4.
|
|
1177
|
+
var nx = magnitudeOf(x);
|
|
1178
|
+
var ny = magnitudeOf(other);
|
|
1072
1179
|
var n = nx / ny;
|
|
1073
1180
|
if (isFinite(n) && n !== 0 && Math.abs(n) <= MAX_SAFE_INTEGER) {
|
|
1074
1181
|
if (Math.abs(n) < 1) return new MetaNum(1 / Math.abs(n)).rec();
|
|
@@ -1111,7 +1218,10 @@
|
|
|
1111
1218
|
var x = this.clone();
|
|
1112
1219
|
// Toggle between large and small: 1↔2, -1↔-2
|
|
1113
1220
|
x.sign = x.sign === 1 ? 2 : x.sign === 2 ? 1 : x.sign === -1 ? -2 : -1;
|
|
1114
|
-
|
|
1221
|
+
// _skipCanon: the reciprocal of a sub-unit value is a NORMAL value (rec(0.5)
|
|
1222
|
+
// = 2) — canonicalizeSubUnit would otherwise flip it straight back.
|
|
1223
|
+
_skipCanon++;
|
|
1224
|
+
try { return x.normalize(); } finally { _skipCanon--; }
|
|
1115
1225
|
};
|
|
1116
1226
|
Q.reciprocate = Q.rec = function (x) {
|
|
1117
1227
|
return new MetaNum(x).rec();
|
|
@@ -1202,7 +1312,11 @@
|
|
|
1202
1312
|
if (other.mod(2).eq(MetaNum.ONE)) return x.abs().root(other).neg();
|
|
1203
1313
|
return MetaNum.NaN.clone();
|
|
1204
1314
|
}
|
|
1205
|
-
if (isNumeric(x) && isNumeric(other))
|
|
1315
|
+
if (isNumeric(x) && isNumeric(other)) {
|
|
1316
|
+
// magnitudeOf: a sub-unit x (sign 2) stores the reciprocal in r0, so
|
|
1317
|
+
// sqrt(0.25) must read 0.25, not the stored 4 (which gave 2).
|
|
1318
|
+
return new MetaNum(Math.pow(magnitudeOf(x), 1 / magnitudeOf(other)));
|
|
1319
|
+
}
|
|
1206
1320
|
// Handle E^m format (iterated exponentiation levels)
|
|
1207
1321
|
if (x.layer === 0 && x.array.length === 1 && x.array[0].length > 1 && isNumeric(other)) {
|
|
1208
1322
|
var r0 = x.array[0];
|
|
@@ -1260,19 +1374,11 @@
|
|
|
1260
1374
|
P.generalLogarithm = P.log10 = function () {
|
|
1261
1375
|
if (this.isNaN() || this.sign === -1 || this.sign === -2) return MetaNum.NaN.clone();
|
|
1262
1376
|
if (this.isInfinite()) return this;
|
|
1263
|
-
if (isSmall(this)) {
|
|
1264
|
-
// Small value: log10 is negative of what it would be for the normal value
|
|
1265
|
-
var n = this.clone();
|
|
1266
|
-
n.sign = 1; // Convert to normal positive for computation
|
|
1267
|
-
var result = n.log10();
|
|
1268
|
-
// Result should be negative (because log10 of a small number is negative)
|
|
1269
|
-
// Need to handle this carefully - after conversion, the result is the magnitude
|
|
1270
|
-
// which we need to negate
|
|
1271
|
-
return result.neg();
|
|
1272
|
-
}
|
|
1273
1377
|
if (this.eq(MetaNum.ZERO)) return MetaNum.NEGATIVE_INFINITY.clone();
|
|
1274
1378
|
if (isNumeric(this)) {
|
|
1275
|
-
|
|
1379
|
+
// magnitudeOf: a sub-unit operand stores the reciprocal in r0, so
|
|
1380
|
+
// log10(0.5) must read 0.5, not the stored 2.
|
|
1381
|
+
var lv = Math.log10(magnitudeOf(this));
|
|
1276
1382
|
if (Number.isFinite(lv)) return new MetaNum(lv);
|
|
1277
1383
|
}
|
|
1278
1384
|
if (this.layer === 0 && this.array.length === 1 && this.array[0].length > 1) {
|
|
@@ -1298,7 +1404,7 @@
|
|
|
1298
1404
|
if (x.eq(MetaNum.ZERO)) return MetaNum.NEGATIVE_INFINITY.clone();
|
|
1299
1405
|
if (x.eq(MetaNum.ONE)) return MetaNum.ZERO.clone();
|
|
1300
1406
|
if (isNumeric(x) && isNumeric(base)) {
|
|
1301
|
-
var lv = Math.log(x
|
|
1407
|
+
var lv = Math.log(magnitudeOf(x)) / Math.log(magnitudeOf(base));
|
|
1302
1408
|
if (Number.isFinite(lv)) return new MetaNum(lv);
|
|
1303
1409
|
}
|
|
1304
1410
|
return x.log10().div(base.log10());
|
|
@@ -1308,11 +1414,14 @@
|
|
|
1308
1414
|
};
|
|
1309
1415
|
|
|
1310
1416
|
P.naturalLogarithm = P.ln = function () {
|
|
1311
|
-
if (this.
|
|
1417
|
+
if (this.sign === -1 || this.sign === -2) return MetaNum.NaN.clone();
|
|
1418
|
+
if (this.isNaN()) return MetaNum.NaN.clone();
|
|
1312
1419
|
if (this.eq(MetaNum.ZERO)) return MetaNum.NEGATIVE_INFINITY.clone();
|
|
1313
1420
|
if (this.isInfinite()) return this;
|
|
1314
1421
|
if (isNumeric(this)) {
|
|
1315
|
-
|
|
1422
|
+
// magnitudeOf: a sub-unit operand stores the reciprocal in r0, so
|
|
1423
|
+
// ln(0.5) must read 0.5, not the stored 2.
|
|
1424
|
+
var lv = Math.log(magnitudeOf(this));
|
|
1316
1425
|
if (Number.isFinite(lv)) return new MetaNum(lv);
|
|
1317
1426
|
}
|
|
1318
1427
|
return this.log10().div(new MetaNum(Math.LOG10E));
|
|
@@ -1354,7 +1463,7 @@
|
|
|
1354
1463
|
if (this.sign === -1 || this.sign === -2) return MetaNum.NaN.clone();
|
|
1355
1464
|
if (this.isNaN() || this.isInfinite()) return this.clone();
|
|
1356
1465
|
if (isSimple(this)) {
|
|
1357
|
-
var n = this
|
|
1466
|
+
var n = magnitudeOf(this); // sub-unit r0 holds the reciprocal
|
|
1358
1467
|
if (Number.isInteger(n) && n >= 0 && n <= 100) {
|
|
1359
1468
|
var f = 1;
|
|
1360
1469
|
for (var i = 2; i < n; i++) f *= i;
|
|
@@ -1377,7 +1486,7 @@
|
|
|
1377
1486
|
if (this.isNaN() || this.isInfinite()) return this;
|
|
1378
1487
|
if (this.sign === -1 || this.sign === -2) return this.abs().fact().neg();
|
|
1379
1488
|
if (isSimple(this)) {
|
|
1380
|
-
var n = this
|
|
1489
|
+
var n = magnitudeOf(this); // sub-unit r0 holds the reciprocal
|
|
1381
1490
|
if (Number.isInteger(n) && n >= 0 && n <= 20) {
|
|
1382
1491
|
var f = 1;
|
|
1383
1492
|
for (var i = 2; i <= n; i++) f *= i;
|
|
@@ -1415,7 +1524,7 @@
|
|
|
1415
1524
|
if (this.gt(MetaNum.E_MAX_SAFE_INTEGER)) return d_lambertw(this, tol, principal);
|
|
1416
1525
|
if (isNumeric(this)) {
|
|
1417
1526
|
try {
|
|
1418
|
-
return new MetaNum(f_lambertw(this
|
|
1527
|
+
return new MetaNum(f_lambertw(magnitudeOf(this), tol, principal));
|
|
1419
1528
|
} catch (e) {
|
|
1420
1529
|
return MetaNum.NaN.clone();
|
|
1421
1530
|
}
|
|
@@ -1428,7 +1537,8 @@
|
|
|
1428
1537
|
if (this.abs().gt(MetaNum.E_MAX_SAFE_INTEGER)) return d_lambertw(this, tol, principal);
|
|
1429
1538
|
if (isNumeric(this)) {
|
|
1430
1539
|
try {
|
|
1431
|
-
return new MetaNum(f_lambertw(
|
|
1540
|
+
return new MetaNum(f_lambertw(
|
|
1541
|
+
(this.sign === -2 ? -1 : this.sign) * magnitudeOf(this.abs()), tol, principal));
|
|
1432
1542
|
} catch (e) {
|
|
1433
1543
|
return MetaNum.NaN.clone();
|
|
1434
1544
|
}
|
|
@@ -1594,7 +1704,7 @@
|
|
|
1594
1704
|
if (this.eq(MetaNum.ZERO)) return MetaNum.ZERO.clone();
|
|
1595
1705
|
if (this.eq(MetaNum.ONE)) return MetaNum.ONE.clone();
|
|
1596
1706
|
if (isSimple(this)) {
|
|
1597
|
-
var v = this
|
|
1707
|
+
var v = magnitudeOf(this);
|
|
1598
1708
|
if (v > 0 && v < 1) return new MetaNum(v);
|
|
1599
1709
|
try {
|
|
1600
1710
|
var w = f_lambertw(Math.log(v));
|
|
@@ -4763,7 +4873,7 @@
|
|
|
4763
4873
|
if (this.isNaN()) return "NaN";
|
|
4764
4874
|
if (this.isInfinite()) return "Infinity";
|
|
4765
4875
|
if (isSimple(this)) {
|
|
4766
|
-
var v = decimalPlaces(this
|
|
4876
|
+
var v = decimalPlaces(magnitudeOf(this), places); // sub-unit r0 = reciprocal
|
|
4767
4877
|
if (Number.isFinite(v)) return v.toString();
|
|
4768
4878
|
}
|
|
4769
4879
|
return this.toString();
|
|
@@ -4779,7 +4889,14 @@
|
|
|
4779
4889
|
if (typeof require == 'function') {
|
|
4780
4890
|
try { formatter = require('./format-metanum.js').format; } catch (e) { formatter = null; }
|
|
4781
4891
|
}
|
|
4782
|
-
|
|
4892
|
+
if (!formatter && typeof format === 'function') formatter = format; // browser bundle
|
|
4893
|
+
if (!formatter) {
|
|
4894
|
+
// No formatter available (bare browser include): fall back to the plain
|
|
4895
|
+
// decimal expansion rather than throwing ReferenceError.
|
|
4896
|
+
var plain = this.toNumber();
|
|
4897
|
+
return isFinite(plain) ? String(plain) : this.toString();
|
|
4898
|
+
}
|
|
4899
|
+
return formatter(this, precision, small);
|
|
4783
4900
|
};
|
|
4784
4901
|
|
|
4785
4902
|
P.toExponential = function (places) {
|
|
@@ -4811,7 +4928,7 @@
|
|
|
4811
4928
|
if (this.isNaN()) return "NaN";
|
|
4812
4929
|
if (this.isInfinite()) return "Infinity";
|
|
4813
4930
|
if (isSimple(this)) {
|
|
4814
|
-
var v = this
|
|
4931
|
+
var v = magnitudeOf(this); // sub-unit r0 holds the reciprocal
|
|
4815
4932
|
if (v < 10) return String(v);
|
|
4816
4933
|
return "E" + Math.log10(v).toFixed(6);
|
|
4817
4934
|
}
|
|
@@ -5891,6 +6008,12 @@
|
|
|
5891
6008
|
// deep for inputs like hardy(1e10+20) where n1≈40 makes every ω^j segment
|
|
5892
6009
|
// take the exact branch: Maximum call stack size exceeded).
|
|
5893
6010
|
Q._hardyH = function (coeffs, nArg) {
|
|
6011
|
+
// Coefficients are read/written STRUCTURALLY below (c[j] -= 1, c[j-1] = n,
|
|
6012
|
+
// c_j compared against HARDY_EXACT_BOUND) and a fractional coefficient is
|
|
6013
|
+
// the normal case once the running base is 10+f — the sub-unit canonical
|
|
6014
|
+
// form must not rewrite them into reciprocals.
|
|
6015
|
+
_skipCanon++;
|
|
6016
|
+
try {
|
|
5894
6017
|
function MN(v) { return (v instanceof MetaNum) ? v.clone() : new MetaNum(v || 0); }
|
|
5895
6018
|
var c = [];
|
|
5896
6019
|
for (var i0 = 0; i0 < coeffs.length; i0++) c.push(MN(coeffs[i0]));
|
|
@@ -5954,6 +6077,7 @@
|
|
|
5954
6077
|
}
|
|
5955
6078
|
// budget exhausted: keep whatever was accumulated (monotone)
|
|
5956
6079
|
return n;
|
|
6080
|
+
} finally { _skipCanon--; }
|
|
5957
6081
|
};
|
|
5958
6082
|
|
|
5959
6083
|
// H_{ω^k}(n) for the from-below base of hardy (n ≥ 1e10).
|
|
@@ -6470,7 +6594,12 @@
|
|
|
6470
6594
|
}
|
|
6471
6595
|
|
|
6472
6596
|
var temp;
|
|
6597
|
+
// Public primitive input: a numeric literal / decimal string in (0,1) or
|
|
6598
|
+
// (-1,0) is stored as the reciprocal with sign 2 / -2. Array/object input
|
|
6599
|
+
// (engine internals, JSON, parsers) is left exactly as given.
|
|
6600
|
+
var publicInput = false;
|
|
6473
6601
|
if (typeof input === "number" && input2 === undefined) {
|
|
6602
|
+
publicInput = true;
|
|
6474
6603
|
temp = objectCreate();
|
|
6475
6604
|
temp.array = [[Math.abs(input)]];
|
|
6476
6605
|
temp.sign = input < 0 ? -1 : 1;
|
|
@@ -6480,6 +6609,7 @@
|
|
|
6480
6609
|
} else if (parsedObject) {
|
|
6481
6610
|
temp = Q.fromObject(parsedObject);
|
|
6482
6611
|
} else if (typeof input === "string") {
|
|
6612
|
+
publicInput = true;
|
|
6483
6613
|
temp = Q.fromString(input);
|
|
6484
6614
|
} else if (Array.isArray(input)) {
|
|
6485
6615
|
temp = Q.fromArray(input, input2, input3);
|
|
@@ -6488,6 +6618,7 @@
|
|
|
6488
6618
|
} else if (typeof input === "object" && input !== null) {
|
|
6489
6619
|
temp = Q.fromObject(input);
|
|
6490
6620
|
} else {
|
|
6621
|
+
publicInput = true;
|
|
6491
6622
|
temp = objectCreate();
|
|
6492
6623
|
var num = Number(input);
|
|
6493
6624
|
if (!isNaN(num) && isFinite(num)) {
|
|
@@ -6503,6 +6634,7 @@
|
|
|
6503
6634
|
temp.sign = num < 0 ? -1 : 1;
|
|
6504
6635
|
}
|
|
6505
6636
|
}
|
|
6637
|
+
if (publicInput) canonicalizeSubUnit(temp);
|
|
6506
6638
|
|
|
6507
6639
|
x.array = deepCloneArray(temp.array);
|
|
6508
6640
|
x.sign = temp.sign;
|
|
@@ -6682,6 +6814,63 @@
|
|
|
6682
6814
|
|
|
6683
6815
|
MetaNum = clone(MetaNum);
|
|
6684
6816
|
MetaNum = defineConstants(MetaNum);
|
|
6817
|
+
|
|
6818
|
+
// Sub-unit canonical form: run the engine's structural CONSUMERS with it off.
|
|
6819
|
+
// These functions read r0 as a plain magnitude and chain through log10/exp
|
|
6820
|
+
// (whose results are now canonicalized when a user calls them directly), so
|
|
6821
|
+
// without this they saw reciprocals where they expected values — gamma(0.5)
|
|
6822
|
+
// read r0 [2] as 2, slog computed from a 3.32 instead of 0.301, and
|
|
6823
|
+
// layeradd/pentate_log returned garbage. The PRODUCERS (constructor with a
|
|
6824
|
+
// primitive, add/sub/mul/div, log10, ln, exp, root, neg) stay canonicalized,
|
|
6825
|
+
// so MetaNum(0.5).sign === 2 and arithmetic results in (0,1) carry sign 2.
|
|
6826
|
+
(function () {
|
|
6827
|
+
var rawConsumers = [
|
|
6828
|
+
'gamma', 'lambertw', 'slog', 'layeradd', 'layeradd10',
|
|
6829
|
+
'pentate', 'pentate_log', 'pentate_root', 'ssrt', 'linear_sroot',
|
|
6830
|
+
'hyper_log', 'hyper_root', 'tetrate', 'expande', 'explode',
|
|
6831
|
+
'expandainate', 'expoiter', 'slayer', 'fastest_hypergrow',
|
|
6832
|
+
'logBase', 'mod', 'arrow'
|
|
6833
|
+
];
|
|
6834
|
+
for (var ri = 0; ri < rawConsumers.length; ri++) {
|
|
6835
|
+
var name = rawConsumers[ri];
|
|
6836
|
+
var fn = P[name];
|
|
6837
|
+
if (typeof fn !== 'function') continue;
|
|
6838
|
+
P[name] = (function (orig) {
|
|
6839
|
+
return function () {
|
|
6840
|
+
_skipCanon++;
|
|
6841
|
+
var out;
|
|
6842
|
+
try { out = orig.apply(this, arguments); }
|
|
6843
|
+
finally { _skipCanon--; }
|
|
6844
|
+
// The hyper-op builders (arrow, tetrate, expande, …) return a
|
|
6845
|
+
// CLOSURE that carries out the real computation — the guard is gone
|
|
6846
|
+
// by then, so the chain ran canonicalized and drifted by an ULP
|
|
6847
|
+
// (4{25}4 → 153.906997547968 instead of …802). Re-arm around it.
|
|
6848
|
+
if (typeof out === 'function') {
|
|
6849
|
+
return function () {
|
|
6850
|
+
_skipCanon++;
|
|
6851
|
+
try { return out.apply(this, arguments); }
|
|
6852
|
+
finally { _skipCanon--; }
|
|
6853
|
+
};
|
|
6854
|
+
}
|
|
6855
|
+
return out;
|
|
6856
|
+
};
|
|
6857
|
+
})(fn);
|
|
6858
|
+
}
|
|
6859
|
+
// Q-level entry points that drive the same structural machinery
|
|
6860
|
+
var rawStatics = ['BEAF', '_beafRecursive', 'arrow', 'beaf'];
|
|
6861
|
+
for (var si = 0; si < rawStatics.length; si++) {
|
|
6862
|
+
var sfn = Q[rawStatics[si]];
|
|
6863
|
+
if (typeof sfn !== 'function') continue;
|
|
6864
|
+
Q[rawStatics[si]] = (function (orig) {
|
|
6865
|
+
return function () {
|
|
6866
|
+
_skipCanon++;
|
|
6867
|
+
try { return orig.apply(this, arguments); }
|
|
6868
|
+
finally { _skipCanon--; }
|
|
6869
|
+
};
|
|
6870
|
+
})(sfn);
|
|
6871
|
+
}
|
|
6872
|
+
})();
|
|
6873
|
+
|
|
6685
6874
|
MetaNum['default'] = MetaNum.MetaNum = MetaNum;
|
|
6686
6875
|
|
|
6687
6876
|
if (typeof define == 'function' && define.amd) {
|