powiaina_num.js 0.2.0-alpha.2.8 → 0.2.0-alpha.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/README.md +98 -72
- package/dist/PowiainaNum.cjs.js +233 -24
- package/dist/PowiainaNum.esm.js +233 -24
- package/dist/PowiainaNum.js +233 -24
- package/dist/PowiainaNum.min.js +1 -1
- package/dist/index.d.ts +21 -3
- package/dist/index.js +1762 -0
- package/dist/types/index.d.ts +184 -0
- package/package.json +47 -47
package/dist/index.js
ADDED
|
@@ -0,0 +1,1762 @@
|
|
|
1
|
+
const powiainaNumError = "[PowiainaNum 0.2 error]";
|
|
2
|
+
const MSI = 9007199254740991;
|
|
3
|
+
const MSI_LOG10 = 15.954589770191003;
|
|
4
|
+
const MSI_REC = 1.1102230246251568e-16;
|
|
5
|
+
const LONG_STRING_MIN_LENGTH = 17;
|
|
6
|
+
const EXP_E_REC = 1.444667861009766;
|
|
7
|
+
const isPowiainaNum = /^(PN)?\/*[-\+]*(Infinity|NaN|(10(\^+|\{([1-9]\d*|!)(,([1-9]\d*|!))?(,[1-9]\d*)?\})|\(10(\^+|\{([1-9]\d*|!)(,([1-9]\d*|!))?(,[1-9]\d*)?\})\)\^[1-9]\d*\x20*)*((\d+(\.\d*)?|\d*\.\d+)?([Ee][-\+]*))*(0|\d+(\.\d*)?|\d*\.\d+))$/;
|
|
8
|
+
function newOperator(r, a = 0, e = 1, m = 1) {
|
|
9
|
+
return {
|
|
10
|
+
repeat: r,
|
|
11
|
+
arrow: a,
|
|
12
|
+
expans: e,
|
|
13
|
+
megota: m,
|
|
14
|
+
valuereplaced: a == Infinity ? 0 : e == Infinity ? 1 : -1,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function compareTuples(...tuples) {
|
|
18
|
+
for (let i = 0; i < Math.min(tuples[0].length, tuples[1].length); i++) {
|
|
19
|
+
const a = tuples[0][i];
|
|
20
|
+
const b = tuples[1][i];
|
|
21
|
+
if (a < b)
|
|
22
|
+
return -1;
|
|
23
|
+
if (a > b)
|
|
24
|
+
return 1;
|
|
25
|
+
}
|
|
26
|
+
return 0;
|
|
27
|
+
}
|
|
28
|
+
function replaceETo10(str) {
|
|
29
|
+
// 使用正则表达式匹配 (e^数字) 的模式
|
|
30
|
+
// 正则解释:\(e\^(\d+)\) 匹配 (e^数字),其中 \d+ 匹配一个或多个数字
|
|
31
|
+
return str.replace(/\(e\^(\d+)\)/g, '(10^)^$1 ').replace(/(\d+)\x20*PT/g, '(10^)^$1 ');
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* 把一个字符串很长的数进行以10为底的对数
|
|
35
|
+
* @param str 被进行的字符串
|
|
36
|
+
* @returns 字符串以10为底的对数;
|
|
37
|
+
*/
|
|
38
|
+
function log10LongString(str) {
|
|
39
|
+
return (Math.log10(Number(str.substring(0, LONG_STRING_MIN_LENGTH))) +
|
|
40
|
+
(str.length - LONG_STRING_MIN_LENGTH));
|
|
41
|
+
}
|
|
42
|
+
function deepCopyProps(source, target) {
|
|
43
|
+
for (let key in source) {
|
|
44
|
+
if (source.hasOwnProperty(key)) {
|
|
45
|
+
// 如果源对象的属性是对象或数组,则递归复制
|
|
46
|
+
if (typeof source[key] === "object" &&
|
|
47
|
+
!(source[key] instanceof PowiainaNum) &&
|
|
48
|
+
source[key] !== null) {
|
|
49
|
+
// 如果目标对象没有这个属性,或者属性是null,则创建一个新的
|
|
50
|
+
if (!target.hasOwnProperty(key) ||
|
|
51
|
+
target[key] == null ||
|
|
52
|
+
Array.isArray(source[key]) !== Array.isArray(target[key])) {
|
|
53
|
+
target[key] = Array.isArray(source[key]) ? [] : {};
|
|
54
|
+
}
|
|
55
|
+
// 递归复制属性
|
|
56
|
+
deepCopyProps(source[key], target[key]);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
// 如果属性不是对象或数组,则直接复制
|
|
60
|
+
target[key] = source[key];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Code from break_eternity.js
|
|
66
|
+
function f_gamma(n) {
|
|
67
|
+
if (!isFinite(n)) {
|
|
68
|
+
return n;
|
|
69
|
+
}
|
|
70
|
+
if (n < -50) {
|
|
71
|
+
if (n === Math.trunc(n)) {
|
|
72
|
+
return Number.NEGATIVE_INFINITY;
|
|
73
|
+
}
|
|
74
|
+
return 0;
|
|
75
|
+
}
|
|
76
|
+
var scal1 = 1;
|
|
77
|
+
while (n < 10) {
|
|
78
|
+
scal1 = scal1 * n;
|
|
79
|
+
++n;
|
|
80
|
+
}
|
|
81
|
+
n -= 1;
|
|
82
|
+
var l = 0.9189385332046727; //0.5*Math.log(2*Math.PI)
|
|
83
|
+
l = l + (n + 0.5) * Math.log(n);
|
|
84
|
+
l = l - n;
|
|
85
|
+
var n2 = n * n;
|
|
86
|
+
var np = n;
|
|
87
|
+
l = l + 1 / (12 * np);
|
|
88
|
+
np = np * n2;
|
|
89
|
+
l = l - 1 / (360 * np);
|
|
90
|
+
np = np * n2;
|
|
91
|
+
l = l + 1 / (1260 * np);
|
|
92
|
+
np = np * n2;
|
|
93
|
+
l = l - 1 / (1680 * np);
|
|
94
|
+
np = np * n2;
|
|
95
|
+
l = l + 1 / (1188 * np);
|
|
96
|
+
np = np * n2;
|
|
97
|
+
l = l - 691 / (360360 * np);
|
|
98
|
+
np = np * n2;
|
|
99
|
+
l = l + 7 / (1092 * np);
|
|
100
|
+
np = np * n2;
|
|
101
|
+
l = l - 3617 / (122400 * np);
|
|
102
|
+
return Math.exp(l) / scal1;
|
|
103
|
+
}
|
|
104
|
+
;
|
|
105
|
+
var _EXPN1 = 0.36787944117144232159553; // exp(-1)
|
|
106
|
+
var OMEGA = 0.56714329040978387299997; // W(1, 0)
|
|
107
|
+
//from https://math.stackexchange.com/a/465183
|
|
108
|
+
// The evaluation can become inaccurate very close to the branch point
|
|
109
|
+
// Evaluates W(x, 0) if principal is true, W(x, -1) if principal is false
|
|
110
|
+
function f_lambertw(z, t = 1e-10, pr = true) {
|
|
111
|
+
var tol = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1e-10;
|
|
112
|
+
var principal = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
|
113
|
+
var w;
|
|
114
|
+
var wn;
|
|
115
|
+
if (!Number.isFinite(z)) {
|
|
116
|
+
return z;
|
|
117
|
+
}
|
|
118
|
+
if (principal) {
|
|
119
|
+
if (z === 0) {
|
|
120
|
+
return z;
|
|
121
|
+
}
|
|
122
|
+
if (z === 1) {
|
|
123
|
+
return OMEGA;
|
|
124
|
+
}
|
|
125
|
+
if (z < 10) {
|
|
126
|
+
w = 0;
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
w = Math.log(z) - Math.log(Math.log(z));
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
if (z === 0)
|
|
134
|
+
return -Infinity;
|
|
135
|
+
if (z <= -0.1) {
|
|
136
|
+
w = -2;
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
w = Math.log(-z) - Math.log(-Math.log(-z));
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
for (var i = 0; i < 100; ++i) {
|
|
143
|
+
wn = (z * Math.exp(-w) + w * w) / (w + 1);
|
|
144
|
+
if (Math.abs(wn - w) < tol * Math.abs(wn)) {
|
|
145
|
+
return wn;
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
w = wn;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
throw Error("Iteration failed to converge: ".concat(z.toString())); //return Number.NaN;
|
|
152
|
+
}
|
|
153
|
+
;
|
|
154
|
+
function isTwoLengthArray(x) {
|
|
155
|
+
return x.length == 2;
|
|
156
|
+
}
|
|
157
|
+
function isTwoNumberArray(x) {
|
|
158
|
+
return typeof x[0] === "number" && typeof x[1] === "number";
|
|
159
|
+
}
|
|
160
|
+
function isExpantaNumArray(x) {
|
|
161
|
+
if (!Array.isArray(x))
|
|
162
|
+
return false;
|
|
163
|
+
for (let i = 0; i < x.length; i++) {
|
|
164
|
+
let arr = x[i];
|
|
165
|
+
if (!Array.isArray(arr))
|
|
166
|
+
return false;
|
|
167
|
+
if (!isTwoLengthArray(arr))
|
|
168
|
+
return false;
|
|
169
|
+
if (!isTwoNumberArray(arr))
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
function countLeadingZerosAfterDecimal(numStr) {
|
|
175
|
+
const match = numStr.match(/^0\.(0*)[1-9]/);
|
|
176
|
+
return match ? match[1].length : 0;
|
|
177
|
+
}
|
|
178
|
+
//from https://github.com/scipy/scipy/blob/8dba340293fe20e62e173bdf2c10ae208286692f/scipy/special/lambertw.pxd
|
|
179
|
+
// The evaluation can become inaccurate very close to the branch point
|
|
180
|
+
// at ``-1/e``. In some corner cases, `lambertw` might currently
|
|
181
|
+
// fail to converge, or can end up on the wrong branch.
|
|
182
|
+
// Evaluates W(x, 0) if principal is true, W(x, -1) if principal is false
|
|
183
|
+
function d_lambertw(z, t = 1e-10, pr = true) {
|
|
184
|
+
var tol = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1e-10;
|
|
185
|
+
var principal = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
|
186
|
+
var w;
|
|
187
|
+
var ew, wewz, wn;
|
|
188
|
+
if (z.isInfiNaN())
|
|
189
|
+
return z;
|
|
190
|
+
if (principal) {
|
|
191
|
+
if (z.eq(PowiainaNum.ZERO)) {
|
|
192
|
+
return PowiainaNum.ZERO.clone();
|
|
193
|
+
}
|
|
194
|
+
if (z.eq(PowiainaNum.ONE)) {
|
|
195
|
+
//Split out this case because the asymptotic series blows up
|
|
196
|
+
return PowiainaNum.fromNumber(OMEGA);
|
|
197
|
+
} //Get an initial guess for Halley's method
|
|
198
|
+
w = z.log();
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
if (z.eq(PowiainaNum.ZERO)) {
|
|
202
|
+
return PowiainaNum.NEGATIVE_INFINITY.clone();
|
|
203
|
+
} //Get an initial guess for Halley's method
|
|
204
|
+
w = z.neg().log();
|
|
205
|
+
} //Halley's method; see 5.9 in [1]
|
|
206
|
+
for (var i = 0; i < 100; ++i) {
|
|
207
|
+
ew = w.neg().exp();
|
|
208
|
+
wewz = w.sub(z.mul(ew));
|
|
209
|
+
wn = w.sub(wewz.div(w.add(1).sub(w.add(2).mul(wewz).div(w.mul(2).add(2)))));
|
|
210
|
+
if (wn.sub(w).abs().lt(wn.abs().mul(tol))) {
|
|
211
|
+
return wn;
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
w = wn;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
throw Error("Iteration failed to converge: ".concat(z.toString())); //return Decimal.dNaN;
|
|
218
|
+
}
|
|
219
|
+
class PowiainaNum {
|
|
220
|
+
constructor(arg1) {
|
|
221
|
+
this.array = [{ arrow: 0, expans: 1, megota: 1, repeat: NaN }];
|
|
222
|
+
this.small = false;
|
|
223
|
+
this.sign = 0;
|
|
224
|
+
this.layer = 0;
|
|
225
|
+
if (typeof arg1 == "undefined") {
|
|
226
|
+
}
|
|
227
|
+
else if (typeof arg1 == "number") {
|
|
228
|
+
let obj = PowiainaNum.fromNumber(arg1);
|
|
229
|
+
this.resetFromObject(obj);
|
|
230
|
+
}
|
|
231
|
+
else if (typeof arg1 == "object") {
|
|
232
|
+
let obj = PowiainaNum.fromObject(arg1);
|
|
233
|
+
this.resetFromObject(obj);
|
|
234
|
+
}
|
|
235
|
+
else if (typeof arg1 == "string") {
|
|
236
|
+
let obj = PowiainaNum.fromString(arg1);
|
|
237
|
+
this.resetFromObject(obj);
|
|
238
|
+
}
|
|
239
|
+
else if (Array.isArray(arg1)) {
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
let isn = arg1;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Addition
|
|
247
|
+
* @returns the sum of `this` and `other`
|
|
248
|
+
*/
|
|
249
|
+
add(other) {
|
|
250
|
+
var _a, _b, _c, _d;
|
|
251
|
+
let x = this.clone();
|
|
252
|
+
let y = new PowiainaNum(other);
|
|
253
|
+
// inf + -inf = nan
|
|
254
|
+
if ((x.eq(PowiainaNum.POSITIVE_INFINITY) &&
|
|
255
|
+
y.eq(PowiainaNum.NEGATIVE_INFINITY)) ||
|
|
256
|
+
(x.eq(PowiainaNum.NEGATIVE_INFINITY) &&
|
|
257
|
+
y.eq(PowiainaNum.POSITIVE_INFINITY)))
|
|
258
|
+
return PowiainaNum.NaN.clone();
|
|
259
|
+
// inf & nan check
|
|
260
|
+
if (!x.isFinite())
|
|
261
|
+
return x.clone();
|
|
262
|
+
if (!y.isFinite())
|
|
263
|
+
return y.clone();
|
|
264
|
+
// if x or y = 0, return other.
|
|
265
|
+
if (x.isZero())
|
|
266
|
+
return y.clone();
|
|
267
|
+
if (y.isZero())
|
|
268
|
+
return x.clone();
|
|
269
|
+
// x+ -x = 0
|
|
270
|
+
if (x.sign == -y.sign &&
|
|
271
|
+
(function () {
|
|
272
|
+
let a = x.abs();
|
|
273
|
+
let b = y.abs();
|
|
274
|
+
return a.eq(b);
|
|
275
|
+
})())
|
|
276
|
+
return PowiainaNum.ZERO.clone();
|
|
277
|
+
// calculate anything > e9e15 or <e-9e15, take absval bigger.
|
|
278
|
+
if (x.abs().lt(PowiainaNum.E_MSI_REC) ||
|
|
279
|
+
x.abs().gt(PowiainaNum.E_MSI) ||
|
|
280
|
+
y.abs().lt(PowiainaNum.E_MSI_REC) ||
|
|
281
|
+
y.abs().gt(PowiainaNum.E_MSI)) {
|
|
282
|
+
return x.maxabs(y);
|
|
283
|
+
}
|
|
284
|
+
if (x.sign == -1) {
|
|
285
|
+
return x.neg().add(y.neg()).neg();
|
|
286
|
+
}
|
|
287
|
+
// if ((x.sign==1&&y.sign==-1&&x.lt(y.abs())) ) return y.neg().add(x.neg()).neg();
|
|
288
|
+
let a, b; //a=bigger, b=smaller
|
|
289
|
+
if (x.cmpabs(y) > 0) {
|
|
290
|
+
a = x;
|
|
291
|
+
b = y;
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
b = x;
|
|
295
|
+
a = y;
|
|
296
|
+
}
|
|
297
|
+
let mult = 1;
|
|
298
|
+
if (!a.small &&
|
|
299
|
+
!b.small &&
|
|
300
|
+
!((_a = a.array[1]) === null || _a === void 0 ? void 0 : _a.repeat) &&
|
|
301
|
+
!((_b = b.array[1]) === null || _b === void 0 ? void 0 : _b.repeat) &&
|
|
302
|
+
a.sign == b.sign) {
|
|
303
|
+
return new PowiainaNum((a.array[0].repeat + b.array[0].repeat) * a.sign);
|
|
304
|
+
}
|
|
305
|
+
const alog10 = (a.small ? -1 : 1) *
|
|
306
|
+
(((_c = a.array[1]) === null || _c === void 0 ? void 0 : _c.repeat) ? a.array[0].repeat : Math.log10(a.array[0].repeat));
|
|
307
|
+
const blog10 = (b.small ? -1 : 1) *
|
|
308
|
+
(((_d = b.array[1]) === null || _d === void 0 ? void 0 : _d.repeat) ? b.array[0].repeat : Math.log10(b.array[0].repeat));
|
|
309
|
+
if (alog10 - blog10 > MSI_LOG10)
|
|
310
|
+
return a;
|
|
311
|
+
const offset = -Math.floor(alog10); //a number can make a+off in [0,1)
|
|
312
|
+
let r, l = 0, t;
|
|
313
|
+
t = a.sign * Math.pow(10, (alog10 + offset)) + b.sign * Math.pow(10, (blog10 + offset));
|
|
314
|
+
if (t > 0)
|
|
315
|
+
l = Math.log10(t) - offset;
|
|
316
|
+
if (t < 0) {
|
|
317
|
+
l = Math.log10(-t) - offset;
|
|
318
|
+
mult *= -1;
|
|
319
|
+
}
|
|
320
|
+
if (t == 0)
|
|
321
|
+
throw Error("Encounter a calculate error");
|
|
322
|
+
r = new PowiainaNum();
|
|
323
|
+
r.sign = 1;
|
|
324
|
+
if (l > MSI_LOG10 || l < -MSI_LOG10) {
|
|
325
|
+
r.array = [newOperator(l, 0), newOperator(1, 1)];
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
r.array = [newOperator(Math.pow(10, Math.abs(l)), 0)];
|
|
329
|
+
}
|
|
330
|
+
r.small = l < 0 ? true : false;
|
|
331
|
+
r.sign *= mult;
|
|
332
|
+
return r;
|
|
333
|
+
}
|
|
334
|
+
static add(t, other) {
|
|
335
|
+
return new PowiainaNum(t).add(other);
|
|
336
|
+
}
|
|
337
|
+
sub(a) {
|
|
338
|
+
return this.add(new PowiainaNum(a).neg());
|
|
339
|
+
}
|
|
340
|
+
static sub(t, other) {
|
|
341
|
+
return new PowiainaNum(t).sub(other);
|
|
342
|
+
}
|
|
343
|
+
mul(other) {
|
|
344
|
+
let x = this.clone();
|
|
345
|
+
let y = new PowiainaNum(other);
|
|
346
|
+
// inf * -inf = -inf
|
|
347
|
+
if ((x.eq(PowiainaNum.POSITIVE_INFINITY) &&
|
|
348
|
+
y.eq(PowiainaNum.NEGATIVE_INFINITY)) ||
|
|
349
|
+
(y.eq(PowiainaNum.POSITIVE_INFINITY) &&
|
|
350
|
+
x.eq(PowiainaNum.NEGATIVE_INFINITY)))
|
|
351
|
+
return PowiainaNum.NEGATIVE_INFINITY.clone();
|
|
352
|
+
if (x.isInfiNaN() &&
|
|
353
|
+
y.eq(PowiainaNum.ZERO) &&
|
|
354
|
+
y.isInfiNaN() &&
|
|
355
|
+
x.eq(PowiainaNum.ZERO))
|
|
356
|
+
return PowiainaNum.NaN.clone();
|
|
357
|
+
if (x.eq(PowiainaNum.NEGATIVE_INFINITY) &&
|
|
358
|
+
y.eq(PowiainaNum.NEGATIVE_INFINITY))
|
|
359
|
+
return PowiainaNum.POSITIVE_INFINITY.clone();
|
|
360
|
+
// inf & nan check
|
|
361
|
+
if (!x.isFinite())
|
|
362
|
+
return x.clone();
|
|
363
|
+
if (!y.isFinite())
|
|
364
|
+
return y.clone();
|
|
365
|
+
if (x.isZero() || y.isZero())
|
|
366
|
+
return PowiainaNum.ZERO.clone();
|
|
367
|
+
// x* x^-1 = 0
|
|
368
|
+
/* if (x.small==1-y.small&&(function(){
|
|
369
|
+
let a = x.abs();
|
|
370
|
+
let b = y.abs();
|
|
371
|
+
return a.eq(b)
|
|
372
|
+
})()) return (function () {
|
|
373
|
+
let a = new PowiainaNum(1);
|
|
374
|
+
a.sign = x.sign*y.sign as -1|0| 1;
|
|
375
|
+
return a;
|
|
376
|
+
})(); */
|
|
377
|
+
let r;
|
|
378
|
+
r = x.abs().log10().add(y.abs().log10()).pow10();
|
|
379
|
+
r.sign = (x.sign * y.sign);
|
|
380
|
+
return r;
|
|
381
|
+
}
|
|
382
|
+
static mul(t, other) {
|
|
383
|
+
return new PowiainaNum(t).mul(other);
|
|
384
|
+
}
|
|
385
|
+
div(other) {
|
|
386
|
+
const x = new PowiainaNum(other).rec();
|
|
387
|
+
return this.mul(x);
|
|
388
|
+
}
|
|
389
|
+
static div(t, other) {
|
|
390
|
+
return new PowiainaNum(t).div(other);
|
|
391
|
+
}
|
|
392
|
+
pow10() {
|
|
393
|
+
var _a, _b;
|
|
394
|
+
const r = this.clone();
|
|
395
|
+
// inf & nan check
|
|
396
|
+
if (!this.isFinite())
|
|
397
|
+
return this.clone();
|
|
398
|
+
if (r.isneg()) {
|
|
399
|
+
// 10^(-x) = 1/(10^x)
|
|
400
|
+
r.sign *= -1;
|
|
401
|
+
return r.pow10().rec();
|
|
402
|
+
}
|
|
403
|
+
if (r.lte(308.25471555991675)) {
|
|
404
|
+
return PowiainaNum.fromNumber(Math.pow(10, (r.toNumber())));
|
|
405
|
+
}
|
|
406
|
+
if (r.small) {
|
|
407
|
+
if (r.lt(PowiainaNum.MSI_REC))
|
|
408
|
+
return PowiainaNum.ONE;
|
|
409
|
+
return new PowiainaNum(Math.pow(10, (Math.pow(r.array[0].repeat, -1))));
|
|
410
|
+
}
|
|
411
|
+
r.setOperator(((_b = (_a = r.array[1]) === null || _a === void 0 ? void 0 : _a.repeat) !== null && _b !== void 0 ? _b : 0) + 1, 1);
|
|
412
|
+
r.normalize();
|
|
413
|
+
return r;
|
|
414
|
+
}
|
|
415
|
+
pow(x) {
|
|
416
|
+
const other = new PowiainaNum(x);
|
|
417
|
+
if (!other.isFinite())
|
|
418
|
+
return other.clone();
|
|
419
|
+
if (!this.isFinite())
|
|
420
|
+
return this.clone();
|
|
421
|
+
if (this.eq(10))
|
|
422
|
+
return other.pow10();
|
|
423
|
+
if (this.isneg()) {
|
|
424
|
+
if (!other.isInt())
|
|
425
|
+
return PowiainaNum.NaN.clone();
|
|
426
|
+
let r = this.abs().pow(other);
|
|
427
|
+
r.sign = (function () {
|
|
428
|
+
let a = other.mod(2).round();
|
|
429
|
+
if (a.eq(0) || a.eq(2))
|
|
430
|
+
return 1;
|
|
431
|
+
return -1;
|
|
432
|
+
})();
|
|
433
|
+
return r;
|
|
434
|
+
}
|
|
435
|
+
let a = this.toNumber();
|
|
436
|
+
let b = other.toNumber();
|
|
437
|
+
let t = Math.pow(a, b);
|
|
438
|
+
if (isFinite(t)) {
|
|
439
|
+
// optimize?
|
|
440
|
+
return PowiainaNum.fromNumber(t);
|
|
441
|
+
}
|
|
442
|
+
// log10(a^b) = b log10(a)
|
|
443
|
+
return this.log10().mul(other).pow10();
|
|
444
|
+
}
|
|
445
|
+
pow_base(x) {
|
|
446
|
+
const a = new PowiainaNum(x);
|
|
447
|
+
return a.pow(this);
|
|
448
|
+
}
|
|
449
|
+
static pow(t, other) {
|
|
450
|
+
return new PowiainaNum(t).pow(other);
|
|
451
|
+
}
|
|
452
|
+
root(x) {
|
|
453
|
+
let other = new PowiainaNum(x);
|
|
454
|
+
return this.pow(other.rec());
|
|
455
|
+
}
|
|
456
|
+
static root(t, other) {
|
|
457
|
+
return new PowiainaNum(t).root(other);
|
|
458
|
+
}
|
|
459
|
+
sqrt() {
|
|
460
|
+
return this.pow(0.5);
|
|
461
|
+
}
|
|
462
|
+
static sqrt(t) {
|
|
463
|
+
return new PowiainaNum(t).sqrt();
|
|
464
|
+
}
|
|
465
|
+
cbrt() {
|
|
466
|
+
return this.root(3);
|
|
467
|
+
}
|
|
468
|
+
static cbrt(t) {
|
|
469
|
+
return new PowiainaNum(t).cbrt();
|
|
470
|
+
}
|
|
471
|
+
// Code from ExpantaNum.js
|
|
472
|
+
tetrate(other2, payload = 1) {
|
|
473
|
+
const t = this.clone();
|
|
474
|
+
let other = new PowiainaNum(other2);
|
|
475
|
+
const payl = new PowiainaNum(payload);
|
|
476
|
+
if (t.isNaN() || other.isNaN() || payl.isNaN())
|
|
477
|
+
return PowiainaNum.NaN.clone();
|
|
478
|
+
if (payl.neq(PowiainaNum.ONE))
|
|
479
|
+
other = other.add(payl.slog(t));
|
|
480
|
+
let negln;
|
|
481
|
+
if (other.isInfi() && other.sign > 0) {
|
|
482
|
+
if (t.gte(EXP_E_REC))
|
|
483
|
+
return PowiainaNum.POSITIVE_INFINITY.clone();
|
|
484
|
+
negln = this.log().neg();
|
|
485
|
+
return negln.lambertw().div(negln);
|
|
486
|
+
}
|
|
487
|
+
if (other.lte(-2))
|
|
488
|
+
return PowiainaNum.NaN.clone();
|
|
489
|
+
if (t.isZero()) {
|
|
490
|
+
if (other.isZero())
|
|
491
|
+
return PowiainaNum.NaN.clone();
|
|
492
|
+
if (other.gte(MSI / 2) || other.toNumber() % 2 == 0)
|
|
493
|
+
return PowiainaNum.ZERO.clone();
|
|
494
|
+
return PowiainaNum.ONE.clone();
|
|
495
|
+
}
|
|
496
|
+
if (t.eq(PowiainaNum.ONE)) {
|
|
497
|
+
if (other.eq(PowiainaNum.ONE.neg()))
|
|
498
|
+
return PowiainaNum.NaN.clone();
|
|
499
|
+
return PowiainaNum.ONE.clone();
|
|
500
|
+
}
|
|
501
|
+
if (other.eq(PowiainaNum.ONE.neg()))
|
|
502
|
+
return PowiainaNum.ZERO.clone();
|
|
503
|
+
if (other.eq(PowiainaNum.ZERO))
|
|
504
|
+
return PowiainaNum.ONE.clone();
|
|
505
|
+
if (other.eq(PowiainaNum.ONE))
|
|
506
|
+
return t;
|
|
507
|
+
if (other.eq(2))
|
|
508
|
+
return t.pow(t);
|
|
509
|
+
if (t.eq(2)) {
|
|
510
|
+
if (other.eq(3))
|
|
511
|
+
return PowiainaNum.fromNumber(16);
|
|
512
|
+
if (other.eq(4))
|
|
513
|
+
return PowiainaNum.fromNumber(65536);
|
|
514
|
+
}
|
|
515
|
+
const m = t.max(other);
|
|
516
|
+
if (m.gt(PowiainaNum.PENTATED_MSI))
|
|
517
|
+
return m;
|
|
518
|
+
if (m.gt(PowiainaNum.TETRATED_MSI) || other.gt(MSI)) {
|
|
519
|
+
if (this.lt(EXP_E_REC)) {
|
|
520
|
+
negln = t.ln().neg();
|
|
521
|
+
return negln.lambertw().div(negln);
|
|
522
|
+
}
|
|
523
|
+
let j = t.slog(10).add(other);
|
|
524
|
+
j.setOperator(j.getOperator(2) + 1, 2);
|
|
525
|
+
j.normalize();
|
|
526
|
+
return j;
|
|
527
|
+
}
|
|
528
|
+
let y = other.toNumber();
|
|
529
|
+
let f = Math.floor(y);
|
|
530
|
+
var r = t.pow(y - f);
|
|
531
|
+
var l = PowiainaNum.NaN;
|
|
532
|
+
let i = 0;
|
|
533
|
+
for (let w = PowiainaNum.E_MSI.clone(); f !== 0 && r.lt(w) && i < 100; ++i) {
|
|
534
|
+
if (f > 0) {
|
|
535
|
+
r = t.pow(r);
|
|
536
|
+
if (l.eq(r)) {
|
|
537
|
+
f = 0;
|
|
538
|
+
break;
|
|
539
|
+
}
|
|
540
|
+
l = r;
|
|
541
|
+
--f;
|
|
542
|
+
}
|
|
543
|
+
else {
|
|
544
|
+
r = r.log(t);
|
|
545
|
+
if (l.eq(r)) {
|
|
546
|
+
f = 0;
|
|
547
|
+
break;
|
|
548
|
+
}
|
|
549
|
+
l = r;
|
|
550
|
+
++f;
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
if (i == 100 || this.lt(EXP_E_REC))
|
|
554
|
+
f = 0;
|
|
555
|
+
r.setOperator(r.getOperator(1) + f, 1);
|
|
556
|
+
r.normalize();
|
|
557
|
+
return r;
|
|
558
|
+
}
|
|
559
|
+
// Code from ExpantaNum.js
|
|
560
|
+
slog(base = 10) {
|
|
561
|
+
let x = this.clone();
|
|
562
|
+
const b = new PowiainaNum(base);
|
|
563
|
+
if (x.isInfiNaN())
|
|
564
|
+
return x;
|
|
565
|
+
if (b.isNaN())
|
|
566
|
+
return b;
|
|
567
|
+
if (b.isInfi())
|
|
568
|
+
return PowiainaNum.ZERO.clone();
|
|
569
|
+
if (x.isZero())
|
|
570
|
+
return PowiainaNum.ONE.clone();
|
|
571
|
+
if (x.eq(PowiainaNum.ONE))
|
|
572
|
+
return PowiainaNum.ZERO.clone();
|
|
573
|
+
if (x.eq(b))
|
|
574
|
+
return PowiainaNum.ONE.clone();
|
|
575
|
+
if (b.lt(EXP_E_REC)) {
|
|
576
|
+
let a = b.tetrate(Infinity);
|
|
577
|
+
if (x.eq(a))
|
|
578
|
+
return PowiainaNum.POSITIVE_INFINITY.clone();
|
|
579
|
+
if (x.gt(a))
|
|
580
|
+
return PowiainaNum.NaN.clone();
|
|
581
|
+
}
|
|
582
|
+
if (x.max(b).gt(PowiainaNum.PENTATED_MSI)) {
|
|
583
|
+
if (x.gt(b))
|
|
584
|
+
return x;
|
|
585
|
+
return PowiainaNum.ZERO.clone();
|
|
586
|
+
}
|
|
587
|
+
if (x.max(b).gt(PowiainaNum.TETRATED_MSI)) {
|
|
588
|
+
if (x.gt(b)) {
|
|
589
|
+
x.setOperator(x.getOperator(2) - 1, 2);
|
|
590
|
+
x.normalize();
|
|
591
|
+
return x.sub(x.getOperator(1));
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
if (x.lt(PowiainaNum.ZERO.clone()))
|
|
595
|
+
return b.pow(x).sub(2);
|
|
596
|
+
let r = 0;
|
|
597
|
+
let t = (x.getOperator(1)) - (b.getOperator(1));
|
|
598
|
+
if (t > 3) {
|
|
599
|
+
let l = t - 3;
|
|
600
|
+
r += l;
|
|
601
|
+
x.setOperator(x.getOperator(1) - l, 1);
|
|
602
|
+
}
|
|
603
|
+
for (let i = 0; i < 100; ++i) {
|
|
604
|
+
if (x.lte(PowiainaNum.ONE))
|
|
605
|
+
return new PowiainaNum(r + x.toNumber());
|
|
606
|
+
++r;
|
|
607
|
+
x = PowiainaNum.log(x, base);
|
|
608
|
+
}
|
|
609
|
+
console.warn("Failed to converage");
|
|
610
|
+
return PowiainaNum.NaN.clone();
|
|
611
|
+
}
|
|
612
|
+
static tetrate(t, other2, payload = 1) {
|
|
613
|
+
return new PowiainaNum(t).tetrate(other2, payload);
|
|
614
|
+
}
|
|
615
|
+
abs() {
|
|
616
|
+
let obj = this.clone();
|
|
617
|
+
if (obj.sign < 0)
|
|
618
|
+
obj.sign *= -1;
|
|
619
|
+
return obj;
|
|
620
|
+
}
|
|
621
|
+
log10() {
|
|
622
|
+
if (this.isneg())
|
|
623
|
+
return PowiainaNum.NaN.clone();
|
|
624
|
+
if (this.isZero())
|
|
625
|
+
return PowiainaNum.NEGATIVE_INFINITY.clone();
|
|
626
|
+
if (this.small) {
|
|
627
|
+
let x = this.clone();
|
|
628
|
+
x.small = !x.small;
|
|
629
|
+
return x.log10().neg();
|
|
630
|
+
}
|
|
631
|
+
if (this.array.length == 1)
|
|
632
|
+
return new PowiainaNum(Math.log10(this.array[0].repeat));
|
|
633
|
+
let x = this.clone();
|
|
634
|
+
x.array[1].repeat = x.array[1].repeat - 1;
|
|
635
|
+
x.normalize();
|
|
636
|
+
return x;
|
|
637
|
+
}
|
|
638
|
+
static log10(t) {
|
|
639
|
+
return new PowiainaNum(t).log10();
|
|
640
|
+
}
|
|
641
|
+
log(base = Math.E) {
|
|
642
|
+
// log_a b = log_x b / log_x a;
|
|
643
|
+
const other = new PowiainaNum(base);
|
|
644
|
+
return this.log10().div(other.log10());
|
|
645
|
+
}
|
|
646
|
+
static log(t, base = Math.E) {
|
|
647
|
+
return new PowiainaNum(t).log(base);
|
|
648
|
+
}
|
|
649
|
+
ln() {
|
|
650
|
+
return this.log();
|
|
651
|
+
}
|
|
652
|
+
static exp(x) {
|
|
653
|
+
let y = new PowiainaNum(x);
|
|
654
|
+
return y.pow_base(Math.E);
|
|
655
|
+
}
|
|
656
|
+
exp() {
|
|
657
|
+
return this.pow_base(Math.E);
|
|
658
|
+
}
|
|
659
|
+
mod(x) {
|
|
660
|
+
const other = new PowiainaNum(x);
|
|
661
|
+
const division = this.div(other);
|
|
662
|
+
return division.sub(division.floor()).mul(other);
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
* For positive integers, X factorial (written as X!) equals X * (X - 1) * (X - 2) *... * 3 * 2 * 1. 0! equals 1.
|
|
666
|
+
* This can be extended to real numbers (except for negative integers) via the gamma function, which is what this function does.
|
|
667
|
+
*/
|
|
668
|
+
//[Code from break_eternity.js]
|
|
669
|
+
factorial() {
|
|
670
|
+
if (this.abs().lt(MSI)) {
|
|
671
|
+
return this.add(1).gamma();
|
|
672
|
+
}
|
|
673
|
+
else if (this.abs().lt(PowiainaNum.E_MSI)) {
|
|
674
|
+
return PowiainaNum.exp(this.mul(this.log10().sub(1)));
|
|
675
|
+
}
|
|
676
|
+
else {
|
|
677
|
+
return PowiainaNum.exp(this);
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
static factorial(x) {
|
|
681
|
+
return new PowiainaNum(x).factorial();
|
|
682
|
+
}
|
|
683
|
+
/**
|
|
684
|
+
* The gamma function extends the idea of factorials to non-whole numbers using some calculus.
|
|
685
|
+
* Gamma(x) is defined as the integral of t^(x-1) * e^-t dt from t = 0 to t = infinity,
|
|
686
|
+
* and gamma(x) = (x - 1)! for nonnegative integer x, so the factorial for non-whole numbers is defined using the gamma function.
|
|
687
|
+
*/
|
|
688
|
+
//[Code from break_eternity.js]
|
|
689
|
+
//from HyperCalc source code
|
|
690
|
+
gamma() {
|
|
691
|
+
if (this.small) {
|
|
692
|
+
return this.rec();
|
|
693
|
+
}
|
|
694
|
+
else if (this.lte(MSI)) {
|
|
695
|
+
if (this.lt(24)) {
|
|
696
|
+
return PowiainaNum.fromNumber(f_gamma(this.sign * this.getOperator(0)));
|
|
697
|
+
}
|
|
698
|
+
var t = this.getOperator(0) - 1;
|
|
699
|
+
var l = 0.9189385332046727; //0.5*Math.log(2*Math.PI)
|
|
700
|
+
l = l + (t + 0.5) * Math.log(t);
|
|
701
|
+
l = l - t;
|
|
702
|
+
var n2 = t * t;
|
|
703
|
+
var np = t;
|
|
704
|
+
var lm = 12 * np;
|
|
705
|
+
var adj = 1 / lm;
|
|
706
|
+
var l2 = l + adj;
|
|
707
|
+
if (l2 === l) {
|
|
708
|
+
return PowiainaNum.exp(l);
|
|
709
|
+
}
|
|
710
|
+
l = l2;
|
|
711
|
+
np = np * n2;
|
|
712
|
+
lm = 360 * np;
|
|
713
|
+
adj = 1 / lm;
|
|
714
|
+
l2 = l - adj;
|
|
715
|
+
if (l2 === l) {
|
|
716
|
+
return PowiainaNum.exp(l);
|
|
717
|
+
}
|
|
718
|
+
l = l2;
|
|
719
|
+
np = np * n2;
|
|
720
|
+
lm = 1260 * np;
|
|
721
|
+
var lt = 1 / lm;
|
|
722
|
+
l = l + lt;
|
|
723
|
+
np = np * n2;
|
|
724
|
+
lm = 1680 * np;
|
|
725
|
+
lt = 1 / lm;
|
|
726
|
+
l = l - lt;
|
|
727
|
+
return PowiainaNum.exp(l);
|
|
728
|
+
}
|
|
729
|
+
else if (this.gt(MSI)) {
|
|
730
|
+
return PowiainaNum.exp(this.mul(this.log().sub(1)));
|
|
731
|
+
}
|
|
732
|
+
else {
|
|
733
|
+
return PowiainaNum.exp(this);
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
static gamma(x) {
|
|
737
|
+
return new PowiainaNum(x).gamma();
|
|
738
|
+
}
|
|
739
|
+
/**
|
|
740
|
+
* The Lambert W function, also called the omega function or product logarithm, is the solution W(x) === x*e^x.
|
|
741
|
+
* https://en.wikipedia.org/wiki/Lambert_W_function
|
|
742
|
+
*
|
|
743
|
+
* This is a multi-valued function in the complex plane, but only two branches matter for real numbers: the "principal branch" W0, and the "non-principal branch" W_-1.
|
|
744
|
+
* W_0 works for any number >= -1/e, but W_-1 only works for nonpositive numbers >= -1/e.
|
|
745
|
+
* The "principal" parameter, which is true by default, decides which branch we're looking for: W_0 is used if principal is true, W_-1 is used if principal is false.
|
|
746
|
+
*/
|
|
747
|
+
//Code from break_eternity.js
|
|
748
|
+
//Some special values, for testing: https://en.wikipedia.org/wiki/Lambert_W_function#Special_values
|
|
749
|
+
lambertw(princ = true) {
|
|
750
|
+
var principal = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
|
|
751
|
+
if (this.lt(-0.3678794411710499)) {
|
|
752
|
+
return PowiainaNum.NaN.clone(); //complex
|
|
753
|
+
}
|
|
754
|
+
else if (principal) {
|
|
755
|
+
if (this.abs().lt("1e-300"))
|
|
756
|
+
return new PowiainaNum(this);
|
|
757
|
+
else if (this.small) {
|
|
758
|
+
return PowiainaNum.fromNumber(f_lambertw(this.toNumber()));
|
|
759
|
+
}
|
|
760
|
+
else if (this.layer === 0) {
|
|
761
|
+
return PowiainaNum.fromNumber(f_lambertw(this.sign * this.getOperator(0)));
|
|
762
|
+
}
|
|
763
|
+
else if (this.lt("eee15")) {
|
|
764
|
+
return d_lambertw(this);
|
|
765
|
+
}
|
|
766
|
+
else {
|
|
767
|
+
// Numbers this large would sometimes fail to converge using d_lambertw, and at this size this.ln() is close enough
|
|
768
|
+
return this.log();
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
else {
|
|
772
|
+
if (this.sign === 1) {
|
|
773
|
+
return PowiainaNum.NaN.clone(); //complex
|
|
774
|
+
}
|
|
775
|
+
if (this.layer === 0) {
|
|
776
|
+
return PowiainaNum.fromNumber(f_lambertw(this.sign * this.array[0].repeat, 1e-10, false));
|
|
777
|
+
}
|
|
778
|
+
else if (this.layer == 1) {
|
|
779
|
+
return d_lambertw(this, 1e-10, false);
|
|
780
|
+
}
|
|
781
|
+
else {
|
|
782
|
+
return this.neg().rec().lambertw().neg();
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
static lambertw(x, principal = true) {
|
|
787
|
+
return new PowiainaNum(x).lambertw(principal);
|
|
788
|
+
}
|
|
789
|
+
static tetrate_10(other2) {
|
|
790
|
+
return PowiainaNum.fromNumber(10).tetrate(other2);
|
|
791
|
+
/*
|
|
792
|
+
const other = new PowiainaNum(other2);
|
|
793
|
+
|
|
794
|
+
const height_int = other.trunc().toNumber();
|
|
795
|
+
const height_frac = other.sub(height_int).toNumber();
|
|
796
|
+
|
|
797
|
+
if (other.gt(PowiainaNum.PENTATED_MSI))
|
|
798
|
+
return other.clone();
|
|
799
|
+
else if (other.gt(PowiainaNum.MSI)) {
|
|
800
|
+
other.setOperator(other.getOperator(2)+1, 2);
|
|
801
|
+
} else if (other.lt(-2))
|
|
802
|
+
return PowiainaNum.NaN.clone();
|
|
803
|
+
else if (other.lt(-1)) {
|
|
804
|
+
return other.add(2).log10();
|
|
805
|
+
}
|
|
806
|
+
else if (other.lt(0)) {
|
|
807
|
+
return other.add(1);
|
|
808
|
+
}else if (other.lt(1)) {
|
|
809
|
+
return other.pow10() // 10^x
|
|
810
|
+
}else if (height_int==1)
|
|
811
|
+
return PowiainaNum.pow(10,PowiainaNum.pow(10,height_frac));
|
|
812
|
+
else if (height_int==2)
|
|
813
|
+
return PowiainaNum.pow(10,PowiainaNum.pow(10,PowiainaNum.pow(10,height_frac)));
|
|
814
|
+
else {
|
|
815
|
+
const remain = height_int-2;
|
|
816
|
+
let a = PowiainaNum.pow(10,PowiainaNum.pow(10,PowiainaNum.pow(10,height_frac)));
|
|
817
|
+
a.setOperator(a.getOperator(1)+remain, 1);
|
|
818
|
+
return a;
|
|
819
|
+
}
|
|
820
|
+
// 1--2, 10-<1e10, 10^10^0->1
|
|
821
|
+
// 2--3, 1e10-<e1e10, 10^10^10^0->1
|
|
822
|
+
return PowiainaNum.NaN.clone();*/
|
|
823
|
+
}
|
|
824
|
+
max(x) {
|
|
825
|
+
const other = new PowiainaNum(x);
|
|
826
|
+
return this.lt(other) ? other.clone() : this.clone();
|
|
827
|
+
}
|
|
828
|
+
min(x) {
|
|
829
|
+
const other = new PowiainaNum(x);
|
|
830
|
+
return this.gte(other) ? other.clone() : this.clone();
|
|
831
|
+
}
|
|
832
|
+
maxabs(x) {
|
|
833
|
+
const other = new PowiainaNum(x).abs();
|
|
834
|
+
return this.abs().lt(other) ? other.clone() : this.clone();
|
|
835
|
+
}
|
|
836
|
+
minabs(x) {
|
|
837
|
+
const other = new PowiainaNum(x).abs();
|
|
838
|
+
return this.abs().gt(other) ? other.clone() : this.clone();
|
|
839
|
+
}
|
|
840
|
+
cmpabs(x) {
|
|
841
|
+
const other = new PowiainaNum(x).abs();
|
|
842
|
+
return this.abs().cmp(other);
|
|
843
|
+
}
|
|
844
|
+
neg() {
|
|
845
|
+
let a = this.clone();
|
|
846
|
+
a.sign *= -1;
|
|
847
|
+
a.normalize();
|
|
848
|
+
return a;
|
|
849
|
+
}
|
|
850
|
+
rec() {
|
|
851
|
+
let a = this.clone();
|
|
852
|
+
a.small = !a.small;
|
|
853
|
+
return a;
|
|
854
|
+
}
|
|
855
|
+
floor() {
|
|
856
|
+
if (this.isInt())
|
|
857
|
+
return this.clone();
|
|
858
|
+
if (this.small) {
|
|
859
|
+
if (this.sign == 1)
|
|
860
|
+
return PowiainaNum.ZERO.clone();
|
|
861
|
+
else
|
|
862
|
+
return PowiainaNum.ONE.neg().clone();
|
|
863
|
+
}
|
|
864
|
+
let r = this.abs();
|
|
865
|
+
r.array[0].repeat = Math[this.sign == 1 ? "floor" : "ceil"](r.getOperator(0));
|
|
866
|
+
return r;
|
|
867
|
+
}
|
|
868
|
+
ceil() {
|
|
869
|
+
if (this.isInt())
|
|
870
|
+
return this.clone();
|
|
871
|
+
if (this.small) {
|
|
872
|
+
if (this.sign == 1)
|
|
873
|
+
return PowiainaNum.ONE.clone();
|
|
874
|
+
else
|
|
875
|
+
return PowiainaNum.ZERO.clone();
|
|
876
|
+
}
|
|
877
|
+
let r = this.abs();
|
|
878
|
+
r.array[0].repeat = Math[this.sign == 1 ? "ceil" : "floor"](r.getOperator(0));
|
|
879
|
+
r.sign = this.sign;
|
|
880
|
+
return r;
|
|
881
|
+
}
|
|
882
|
+
round() {
|
|
883
|
+
if (this.isInt())
|
|
884
|
+
return this.clone();
|
|
885
|
+
if (this.small) {
|
|
886
|
+
if (this.sign == 1) {
|
|
887
|
+
if (this.rec().lte(2))
|
|
888
|
+
return PowiainaNum.ONE.clone();
|
|
889
|
+
else
|
|
890
|
+
return PowiainaNum.ZERO.clone();
|
|
891
|
+
}
|
|
892
|
+
else {
|
|
893
|
+
if (this.abs().rec().lte(2))
|
|
894
|
+
return PowiainaNum.ZERO.clone();
|
|
895
|
+
else
|
|
896
|
+
return PowiainaNum.ONE.neg().clone();
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
let r = this.abs();
|
|
900
|
+
r.array[0].repeat = Math.round(r.array[0].repeat);
|
|
901
|
+
r.sign = this.sign;
|
|
902
|
+
return r;
|
|
903
|
+
}
|
|
904
|
+
/**
|
|
905
|
+
* Work like `Math.trunc`,
|
|
906
|
+
*
|
|
907
|
+
* if `this > 0`, return `floor(this)`
|
|
908
|
+
*
|
|
909
|
+
* if `this < 0`, return `ceil(this)`
|
|
910
|
+
*
|
|
911
|
+
* @example
|
|
912
|
+
* new PowiainaNum(3.3).trunc() == new PowiainaNum(3)
|
|
913
|
+
* new PowiainaNum(-1.114514).trunc() == new PowiainaNum(-1)
|
|
914
|
+
* @returns
|
|
915
|
+
*/
|
|
916
|
+
trunc() {
|
|
917
|
+
const y = this.clone();
|
|
918
|
+
return y.gte(0) ? y.floor() : y.ceil();
|
|
919
|
+
}
|
|
920
|
+
/**
|
|
921
|
+
* @returns if this<other, return -1, if this=other, return 0, if this>other, return 1, if this!<=>, return 2
|
|
922
|
+
*/
|
|
923
|
+
compare(x) {
|
|
924
|
+
const other = new PowiainaNum(x);
|
|
925
|
+
if (this.isNaN() || other.isNaN())
|
|
926
|
+
return 2;
|
|
927
|
+
if (this.sign < other.sign)
|
|
928
|
+
return -1;
|
|
929
|
+
if (this.sign > other.sign)
|
|
930
|
+
return 1;
|
|
931
|
+
//this.sign = other.sign
|
|
932
|
+
const allneg = this.sign == -1 && other.sign == -1;
|
|
933
|
+
if (this.small && !other.small)
|
|
934
|
+
return (-1 * (allneg ? -1 : 1));
|
|
935
|
+
if (other.small && !this.small)
|
|
936
|
+
return (1 * (allneg ? -1 : 1));
|
|
937
|
+
let resultreverse = 1;
|
|
938
|
+
if (this.small && other.small)
|
|
939
|
+
resultreverse *= -1;
|
|
940
|
+
if (allneg)
|
|
941
|
+
resultreverse *= -1;
|
|
942
|
+
let result = 0;
|
|
943
|
+
for (let i = 0; this.array.length - 1 - i >= 0 && other.array.length - 1 - i >= 0; i++) {
|
|
944
|
+
let op1 = this.array[this.array.length - 1 - i];
|
|
945
|
+
let op2 = other.array[other.array.length - 1 - i];
|
|
946
|
+
let cmp = compareTuples([op1.megota, op1.expans, op1.arrow, op1.repeat], [op2.megota, op2.expans, op2.arrow, op2.repeat]);
|
|
947
|
+
if (cmp == 1) {
|
|
948
|
+
result = 1;
|
|
949
|
+
break;
|
|
950
|
+
}
|
|
951
|
+
else if (cmp == -1) {
|
|
952
|
+
result = -1;
|
|
953
|
+
break;
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
return (result * resultreverse + 1 - 1);
|
|
957
|
+
}
|
|
958
|
+
cmp(other) {
|
|
959
|
+
return this.compare(other);
|
|
960
|
+
}
|
|
961
|
+
eq(other) {
|
|
962
|
+
return this.cmp(other) === 0;
|
|
963
|
+
}
|
|
964
|
+
neq(other) {
|
|
965
|
+
return this.cmp(other) !== 0;
|
|
966
|
+
}
|
|
967
|
+
lt(other) {
|
|
968
|
+
return this.cmp(other) === -1;
|
|
969
|
+
}
|
|
970
|
+
lte(other) {
|
|
971
|
+
return this.cmp(other) <= 0;
|
|
972
|
+
}
|
|
973
|
+
gt(other) {
|
|
974
|
+
return this.cmp(other) == 1;
|
|
975
|
+
}
|
|
976
|
+
gte(other) {
|
|
977
|
+
let t = this.cmp(other);
|
|
978
|
+
return t == 0 || t == 1;
|
|
979
|
+
}
|
|
980
|
+
isNaN() {
|
|
981
|
+
return isNaN(this.getOperator(0));
|
|
982
|
+
}
|
|
983
|
+
isZero() {
|
|
984
|
+
return Boolean(this.small && !isFinite(this.getOperator(0)));
|
|
985
|
+
}
|
|
986
|
+
isFinite() {
|
|
987
|
+
return (Boolean(this.small || isFinite(this.getOperator(0))) && !this.isNaN());
|
|
988
|
+
}
|
|
989
|
+
isInfi() {
|
|
990
|
+
return this.rec().isZero();
|
|
991
|
+
}
|
|
992
|
+
isInfiNaN() {
|
|
993
|
+
return this.isInfi() || this.isNaN();
|
|
994
|
+
}
|
|
995
|
+
isInt() {
|
|
996
|
+
if (this.isZero())
|
|
997
|
+
return true;
|
|
998
|
+
if (!this.small && Number.isInteger(this.getOperator(0)))
|
|
999
|
+
return true;
|
|
1000
|
+
if (this.abs().gte(MSI / 2))
|
|
1001
|
+
return true;
|
|
1002
|
+
return false;
|
|
1003
|
+
}
|
|
1004
|
+
ispos() {
|
|
1005
|
+
return this.sign > 0;
|
|
1006
|
+
}
|
|
1007
|
+
isneg() {
|
|
1008
|
+
return this.sign < 0;
|
|
1009
|
+
}
|
|
1010
|
+
static isNaN(x) {
|
|
1011
|
+
return new PowiainaNum(x).isNaN();
|
|
1012
|
+
}
|
|
1013
|
+
/**
|
|
1014
|
+
* Normalize functions will make this number convert into standard format.(it also change `this`, like [].sort)
|
|
1015
|
+
* @returns normalized number
|
|
1016
|
+
*/
|
|
1017
|
+
normalize() {
|
|
1018
|
+
//TODO: normalize
|
|
1019
|
+
let renormalize = true;
|
|
1020
|
+
var x = this;
|
|
1021
|
+
for (let i = 0; i < this.array.length; i++) {
|
|
1022
|
+
// Check what is infinity
|
|
1023
|
+
if (this.array[i].repeat == Infinity) {
|
|
1024
|
+
this.array = [
|
|
1025
|
+
{
|
|
1026
|
+
arrow: 0,
|
|
1027
|
+
expans: 1,
|
|
1028
|
+
megota: 1,
|
|
1029
|
+
repeat: Infinity,
|
|
1030
|
+
},
|
|
1031
|
+
];
|
|
1032
|
+
this.layer = 0;
|
|
1033
|
+
return this;
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
for (var i = 1; i < x.array.length; ++i) {
|
|
1037
|
+
var e = x.array[i];
|
|
1038
|
+
if (e.arrow === null || e.arrow === undefined) {
|
|
1039
|
+
e.arrow = 0;
|
|
1040
|
+
}
|
|
1041
|
+
if (e.expans === null || e.expans === undefined) {
|
|
1042
|
+
e.expans = 1;
|
|
1043
|
+
}
|
|
1044
|
+
if (e.megota === null || e.megota === undefined) {
|
|
1045
|
+
e.megota = 1;
|
|
1046
|
+
}
|
|
1047
|
+
if (isNaN(e.arrow) ||
|
|
1048
|
+
isNaN(e.repeat) ||
|
|
1049
|
+
isNaN(e.expans) ||
|
|
1050
|
+
isNaN(e.megota)) {
|
|
1051
|
+
x.array = [newOperator(NaN, 0, 1, 1)];
|
|
1052
|
+
return x;
|
|
1053
|
+
}
|
|
1054
|
+
if (!isFinite(e.repeat) || !isFinite(e.megota)) {
|
|
1055
|
+
x.array = [newOperator(Infinity, 0, 1, 1)];
|
|
1056
|
+
return x;
|
|
1057
|
+
}
|
|
1058
|
+
if (!Number.isInteger(e.arrow))
|
|
1059
|
+
e.arrow = Math.floor(e.arrow);
|
|
1060
|
+
if (!Number.isInteger(e.repeat))
|
|
1061
|
+
e.repeat = Math.floor(e.repeat);
|
|
1062
|
+
if (!Number.isInteger(e.expans))
|
|
1063
|
+
e.expans = Math.floor(e.expans);
|
|
1064
|
+
if (!Number.isInteger(e.megota))
|
|
1065
|
+
e.megota = Math.floor(e.megota);
|
|
1066
|
+
}
|
|
1067
|
+
if (!x.array.length) {
|
|
1068
|
+
x.small = !x.small;
|
|
1069
|
+
x.array = [newOperator(Infinity)]; // if no array set zero
|
|
1070
|
+
}
|
|
1071
|
+
do {
|
|
1072
|
+
renormalize = false;
|
|
1073
|
+
// Sort arrays.
|
|
1074
|
+
this.array.sort(function (a, b) {
|
|
1075
|
+
return compareTuples([a.megota, a.expans, a.arrow], [b.megota, b.expans, b.arrow]);
|
|
1076
|
+
});
|
|
1077
|
+
for (i = 1; i < x.array.length - 1; ++i) {
|
|
1078
|
+
if (x.array[i].arrow == x.array[i + 1].arrow &&
|
|
1079
|
+
x.array[i].expans == x.array[i + 1].expans &&
|
|
1080
|
+
x.array[i].megota == x.array[i + 1].megota) {
|
|
1081
|
+
// same array's merge
|
|
1082
|
+
x.array[i].repeat += x.array[i + 1].repeat;
|
|
1083
|
+
x.array.splice(i + 1, 1);
|
|
1084
|
+
--i;
|
|
1085
|
+
renormalize = true;
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
for (i = 1; i < x.array.length; ++i) {
|
|
1089
|
+
// If there is a 0 repeat operator, remove it.
|
|
1090
|
+
if (x.array[i].arrow !== 0 &&
|
|
1091
|
+
(x.array[i].repeat === 0 ||
|
|
1092
|
+
x.array[i].repeat === null ||
|
|
1093
|
+
x.array[i].repeat === undefined)) {
|
|
1094
|
+
x.array.splice(i, 1);
|
|
1095
|
+
--i;
|
|
1096
|
+
continue;
|
|
1097
|
+
}
|
|
1098
|
+
// If there is a operator which arrow 0 and brace count >=2
|
|
1099
|
+
// replace it as arrow replacement operaotr
|
|
1100
|
+
if (x.array[i].arrow == 0 && x.array[i].expans >= 2) {
|
|
1101
|
+
x.array[i].arrow = Infinity;
|
|
1102
|
+
x.array[i].valuereplaced = 0;
|
|
1103
|
+
x.array[i].expans = x.array[i].expans - 1;
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
if (x.array.length > PowiainaNum.maxOps)
|
|
1107
|
+
x.array.splice(1, x.array.length - PowiainaNum.maxOps); // max operators check
|
|
1108
|
+
// for any 10^a but a >log10(MSI), replace to regular 10^a
|
|
1109
|
+
if (this.getOperator(1) >= 1 && this.getOperator(0) < MSI_LOG10) {
|
|
1110
|
+
this.setOperator(this.getOperator(1) - 1, 1);
|
|
1111
|
+
this.setOperator(Math.pow(10, this.getOperator(0)), 0);
|
|
1112
|
+
renormalize = true;
|
|
1113
|
+
}
|
|
1114
|
+
if (this.getOperator(0) > MSI) {
|
|
1115
|
+
this.setOperator(this.getOperator(1) + 1, 1);
|
|
1116
|
+
this.setOperator(Math.log10(this.getOperator(0)), 0);
|
|
1117
|
+
renormalize = true;
|
|
1118
|
+
}
|
|
1119
|
+
// for a<1, turn into reciprocate
|
|
1120
|
+
if (this.array.length == 1 && this.array[0].repeat < 1) {
|
|
1121
|
+
this.array[0].repeat = 1 / this.array[0].repeat;
|
|
1122
|
+
this.small = !this.small;
|
|
1123
|
+
renormalize = true;
|
|
1124
|
+
}
|
|
1125
|
+
while (x.array.length >= 2 &&
|
|
1126
|
+
x.array[0].repeat == 1 &&
|
|
1127
|
+
x.array[1].repeat) {
|
|
1128
|
+
// for any 10{X}10{X} 1, turn into 10{X}10
|
|
1129
|
+
// [1, [R=sth, A=sth, E=sth, M=sth]]
|
|
1130
|
+
if (x.array[1].repeat > 1) {
|
|
1131
|
+
x.array[1].repeat--;
|
|
1132
|
+
}
|
|
1133
|
+
else {
|
|
1134
|
+
x.array.splice(1, 1);
|
|
1135
|
+
}
|
|
1136
|
+
x.array[0].repeat = 10;
|
|
1137
|
+
renormalize = true;
|
|
1138
|
+
}
|
|
1139
|
+
if (x.array.length >= 2 &&
|
|
1140
|
+
x.array[0].repeat < MSI &&
|
|
1141
|
+
x.array[1].arrow >= 2 &&
|
|
1142
|
+
x.array[1].repeat == 1 &&
|
|
1143
|
+
isFinite(x.array[1].arrow)) {
|
|
1144
|
+
// for any 10{A sample=2}1e9, turn into (10{A-1})^1e9-1 10
|
|
1145
|
+
// But dont convert when a is infinite
|
|
1146
|
+
// [1e9, [R=1, A=2, sth, sth]]
|
|
1147
|
+
x.array.splice(1, 1, newOperator(x.array[0].repeat, x.array[1].arrow - 1, x.array[1].expans, x.array[1].megota));
|
|
1148
|
+
x.array[0].repeat = 10;
|
|
1149
|
+
renormalize = true;
|
|
1150
|
+
}
|
|
1151
|
+
// for any (10{A=2})^1e16 10, turn into (10{A+1}) 1e16
|
|
1152
|
+
if (x.array.length >= 2 &&
|
|
1153
|
+
x.array[1].repeat > MSI) {
|
|
1154
|
+
x.array[1].arrow++;
|
|
1155
|
+
x.array[0].repeat = x.array[1].repeat;
|
|
1156
|
+
x.array[1].repeat = 1;
|
|
1157
|
+
renormalize = true;
|
|
1158
|
+
}
|
|
1159
|
+
} while (renormalize);
|
|
1160
|
+
return this;
|
|
1161
|
+
}
|
|
1162
|
+
/**
|
|
1163
|
+
* @returns number will return the index of the operator in array. return as x.5 if it's between the xth and x+1th operators.
|
|
1164
|
+
*/
|
|
1165
|
+
getOperatorIndex(arrow, expans = 1, megota = 1) {
|
|
1166
|
+
if (this.array.length == 1 && arrow == 0)
|
|
1167
|
+
return 0;
|
|
1168
|
+
if (this.array.length == 1 && arrow == 1)
|
|
1169
|
+
return 0.5;
|
|
1170
|
+
if (this.array.length == 2 && arrow == 1)
|
|
1171
|
+
return 1;
|
|
1172
|
+
if (this.array.length == 2 && arrow == 0)
|
|
1173
|
+
return 0;
|
|
1174
|
+
for (let i = 0; i < this.array.length; i++) {
|
|
1175
|
+
let cmp = compareTuples([this.array[i].megota, this.array[i].expans, this.array[i].arrow], [megota, expans, arrow]);
|
|
1176
|
+
if (cmp == 0)
|
|
1177
|
+
return i; // I find it was [xx,xxx,*xxx*,xxx]!
|
|
1178
|
+
if (cmp == 1)
|
|
1179
|
+
return i - 0.5; // It's between [xx, xx,xx*,?,*xx]!
|
|
1180
|
+
}
|
|
1181
|
+
return this.array.length - 0.5;
|
|
1182
|
+
}
|
|
1183
|
+
/**
|
|
1184
|
+
* @returns number repeats of operators with given arguments.
|
|
1185
|
+
*/
|
|
1186
|
+
getOperator(arrow, expans = 1, megota = 1) {
|
|
1187
|
+
const index = this.getOperatorIndex(arrow, expans, megota);
|
|
1188
|
+
if (!this.array[index])
|
|
1189
|
+
return 0;
|
|
1190
|
+
return this.array[index].repeat;
|
|
1191
|
+
}
|
|
1192
|
+
/**
|
|
1193
|
+
* Modify the repeat of operator
|
|
1194
|
+
* @param number val the repeat of operator will modify to array.
|
|
1195
|
+
* @returns bool Is the operators array changed?
|
|
1196
|
+
*/
|
|
1197
|
+
setOperator(val, arrow, expans = 1, megota = 1) {
|
|
1198
|
+
// if (arrow!=0&&val==0) return false;
|
|
1199
|
+
const index = this.getOperatorIndex(arrow, expans, megota);
|
|
1200
|
+
if (!this.array[index]) {
|
|
1201
|
+
this.array.splice(Math.ceil(index), 0, {
|
|
1202
|
+
arrow,
|
|
1203
|
+
expans,
|
|
1204
|
+
megota,
|
|
1205
|
+
valuereplaced: expans === Infinity ? 1 : arrow == Infinity ? 0 : -1,
|
|
1206
|
+
repeat: val,
|
|
1207
|
+
});
|
|
1208
|
+
return true;
|
|
1209
|
+
}
|
|
1210
|
+
this.array[index].repeat = val;
|
|
1211
|
+
// this.normalize()
|
|
1212
|
+
return false;
|
|
1213
|
+
}
|
|
1214
|
+
/**
|
|
1215
|
+
* @returns a PowiainaNum object which deep copied from `this` object.
|
|
1216
|
+
*/
|
|
1217
|
+
clone() {
|
|
1218
|
+
let obj = new PowiainaNum();
|
|
1219
|
+
obj.resetFromObject(this);
|
|
1220
|
+
return obj;
|
|
1221
|
+
}
|
|
1222
|
+
resetFromObject(powlikeObject) {
|
|
1223
|
+
this.array = [];
|
|
1224
|
+
for (let i = 0; i < powlikeObject.array.length; i++) {
|
|
1225
|
+
this.array[i] = {
|
|
1226
|
+
arrow: powlikeObject.array[i].arrow,
|
|
1227
|
+
expans: powlikeObject.array[i].expans,
|
|
1228
|
+
megota: powlikeObject.array[i].megota,
|
|
1229
|
+
repeat: powlikeObject.array[i].repeat,
|
|
1230
|
+
valuereplaced: powlikeObject.array[i].valuereplaced,
|
|
1231
|
+
};
|
|
1232
|
+
}
|
|
1233
|
+
this.small = powlikeObject.small;
|
|
1234
|
+
this.sign = powlikeObject.sign;
|
|
1235
|
+
this.layer = powlikeObject.layer;
|
|
1236
|
+
return this;
|
|
1237
|
+
}
|
|
1238
|
+
/**
|
|
1239
|
+
* Convert `this` to Javascript `number`
|
|
1240
|
+
*
|
|
1241
|
+
* returns `Infinity` when the number is greater than `Number.MAX_VALUE`
|
|
1242
|
+
*/
|
|
1243
|
+
toNumber() {
|
|
1244
|
+
if (this.sign == -1)
|
|
1245
|
+
return -this.neg().toNumber();
|
|
1246
|
+
if (this.small)
|
|
1247
|
+
return 1 / this.rec().toNumber();
|
|
1248
|
+
if (this.array.length > 2)
|
|
1249
|
+
return Infinity;
|
|
1250
|
+
if (this.array.length == 1)
|
|
1251
|
+
return this.array[0].repeat;
|
|
1252
|
+
else if (this.array.length == 2 && this.array[1].arrow == 1 && this.array[1].expans == 1 && this.array[1].megota == 1 && this.array[1].repeat == 1)
|
|
1253
|
+
return Math.pow(10, this.getOperator(0));
|
|
1254
|
+
return NaN;
|
|
1255
|
+
}
|
|
1256
|
+
/**
|
|
1257
|
+
* Convert `this` to a string
|
|
1258
|
+
*/
|
|
1259
|
+
toString() {
|
|
1260
|
+
if (this.isNaN())
|
|
1261
|
+
return `NaN`;
|
|
1262
|
+
if (this.sign == -1)
|
|
1263
|
+
return `-${this.neg().toString()}`;
|
|
1264
|
+
if (this.small) {
|
|
1265
|
+
if (this.isZero())
|
|
1266
|
+
return `0`;
|
|
1267
|
+
return `/${this.rec().toString()}`;
|
|
1268
|
+
}
|
|
1269
|
+
if (this.isInfi())
|
|
1270
|
+
return `Infinity`;
|
|
1271
|
+
// O^a (10{arrow,expans,megota})^repeation base
|
|
1272
|
+
let res = ``;
|
|
1273
|
+
for (let i = this.array.length - 1; i >= 0; i--) {
|
|
1274
|
+
let oper = this.array[i];
|
|
1275
|
+
let calc = `10{${oper.arrow === Infinity ? "!" : oper.arrow}${oper.expans > 1 || oper.megota > 1
|
|
1276
|
+
? `,${oper.expans === Infinity ? "!" : oper.expans}`
|
|
1277
|
+
: ""}${oper.megota > 1 ? `,${oper.megota}` : ""}}`;
|
|
1278
|
+
if (oper.arrow == 1 &&
|
|
1279
|
+
oper.expans == 1 &&
|
|
1280
|
+
oper.megota == 1 &&
|
|
1281
|
+
oper.repeat < 5) {
|
|
1282
|
+
calc = `e`.repeat(oper.repeat);
|
|
1283
|
+
}
|
|
1284
|
+
else if (oper.arrow == 0 && oper.expans == 1 && oper.megota == 1) {
|
|
1285
|
+
calc = oper.repeat.toString();
|
|
1286
|
+
}
|
|
1287
|
+
else if (oper.repeat > 1) {
|
|
1288
|
+
calc = `(${calc})^${oper.repeat} `;
|
|
1289
|
+
}
|
|
1290
|
+
else {
|
|
1291
|
+
calc = `${calc}`;
|
|
1292
|
+
}
|
|
1293
|
+
res += `${calc}`;
|
|
1294
|
+
}
|
|
1295
|
+
return res;
|
|
1296
|
+
}
|
|
1297
|
+
static fromNumber(x) {
|
|
1298
|
+
let obj = new PowiainaNum(); // NaN
|
|
1299
|
+
if (x < 0)
|
|
1300
|
+
obj.sign = -1; // negative
|
|
1301
|
+
else if (x == 0) {
|
|
1302
|
+
obj.sign = 0;
|
|
1303
|
+
obj.small = true;
|
|
1304
|
+
obj.array = [newOperator(Infinity, 0)];
|
|
1305
|
+
return obj;
|
|
1306
|
+
}
|
|
1307
|
+
else if (x > 0)
|
|
1308
|
+
obj.sign = 1;
|
|
1309
|
+
let y = Math.abs(x);
|
|
1310
|
+
if (y >= MSI_REC && y < 1) {
|
|
1311
|
+
obj.small = true;
|
|
1312
|
+
obj.array = [newOperator(1 / y, 0)];
|
|
1313
|
+
}
|
|
1314
|
+
else if (y < MSI_REC) {
|
|
1315
|
+
obj.small = true;
|
|
1316
|
+
obj.array = [newOperator(-Math.log10(y), 0), newOperator(1, 1)];
|
|
1317
|
+
}
|
|
1318
|
+
else if (y <= MSI) {
|
|
1319
|
+
obj.array = [newOperator(y, 0)];
|
|
1320
|
+
}
|
|
1321
|
+
else {
|
|
1322
|
+
obj.setOperator(Math.log10(y), 0);
|
|
1323
|
+
obj.array = [newOperator(Math.log10(y), 0), newOperator(1, 1)];
|
|
1324
|
+
}
|
|
1325
|
+
return obj;
|
|
1326
|
+
}
|
|
1327
|
+
/**
|
|
1328
|
+
* Convert `this` to a JSON object
|
|
1329
|
+
* @returns a JSON object
|
|
1330
|
+
*/
|
|
1331
|
+
toJSON() {
|
|
1332
|
+
return "PN" + this.toString();
|
|
1333
|
+
}
|
|
1334
|
+
static fromString(input) {
|
|
1335
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1336
|
+
var x = new PowiainaNum();
|
|
1337
|
+
// Judge the string was a number
|
|
1338
|
+
if (input.startsWith("PN"))
|
|
1339
|
+
input = input.substring(2);
|
|
1340
|
+
if (!isNaN(Number(input))) {
|
|
1341
|
+
let res = Number(input);
|
|
1342
|
+
let a = false;
|
|
1343
|
+
if (res == 0) {
|
|
1344
|
+
if (/^(0*\.0*e)|(0*\.0*)$/.test(input)) {
|
|
1345
|
+
a = true;
|
|
1346
|
+
}
|
|
1347
|
+
}
|
|
1348
|
+
else {
|
|
1349
|
+
a = true;
|
|
1350
|
+
}
|
|
1351
|
+
if (!a) {
|
|
1352
|
+
/**
|
|
1353
|
+
* Possible forms:
|
|
1354
|
+
* 1.33e-114514
|
|
1355
|
+
* 0.000000114514e-114514
|
|
1356
|
+
* 0.00....00114514e-1919810
|
|
1357
|
+
*
|
|
1358
|
+
* 0.0000000...0000000114514
|
|
1359
|
+
* 100000.....000000e-1919810
|
|
1360
|
+
* TODO: 1.0000e-1000000....00000
|
|
1361
|
+
*/
|
|
1362
|
+
let m = input.search(/e/);
|
|
1363
|
+
let exponent = input.substring((m == -2 ? input.length : m) + 1);
|
|
1364
|
+
let mantissa = input.substring(0, m == -2 ? undefined : m);
|
|
1365
|
+
let mantissaME = [0, 0];
|
|
1366
|
+
// Handle mantissa to ME
|
|
1367
|
+
mantissaME[1] = Number(exponent ? exponent : "0");
|
|
1368
|
+
console.log(mantissa);
|
|
1369
|
+
// Is regular number gte 1:
|
|
1370
|
+
if (Number(mantissa) >= 1) {
|
|
1371
|
+
// check The mantissa is very long?
|
|
1372
|
+
let log10mant = mantissa.length >= LONG_STRING_MIN_LENGTH ? log10LongString(mantissa) : Math.log10(Number(mantissa));
|
|
1373
|
+
let log10int = Math.floor(log10mant) - 1;
|
|
1374
|
+
let log10float = log10mant - log10int;
|
|
1375
|
+
mantissaME[0] = Math.pow(10, log10float);
|
|
1376
|
+
mantissaME[1] += log10float;
|
|
1377
|
+
console.log(mantissaME);
|
|
1378
|
+
}
|
|
1379
|
+
else {
|
|
1380
|
+
// If not , count how many zeros until reached non-zero numbers
|
|
1381
|
+
let zeros = countLeadingZerosAfterDecimal(mantissa);
|
|
1382
|
+
mantissa = mantissa.substring(mantissa.search(/[1-9]/));
|
|
1383
|
+
console.log(mantissa);
|
|
1384
|
+
mantissa = mantissa[0].charAt(0) + "." + mantissa.substring(1);
|
|
1385
|
+
zeros += 1;
|
|
1386
|
+
mantissaME[0] = Number(mantissa);
|
|
1387
|
+
mantissaME[1] += -zeros;
|
|
1388
|
+
}
|
|
1389
|
+
// We'll get [a, b] which respents a*10^b;
|
|
1390
|
+
// actually b < 0; So we can ^-1
|
|
1391
|
+
// /((a*10^b)^-1) = /(a^-1*10^-b) = /(a^-1 * 10 * 10^(-b-1))
|
|
1392
|
+
console.log(mantissaME);
|
|
1393
|
+
return PowiainaNum.pow(10, -mantissaME[1] - 1).mul(Math.pow(mantissaME[0], -1) * 10).rec();
|
|
1394
|
+
}
|
|
1395
|
+
if (isFinite(res) && a) {
|
|
1396
|
+
x.resetFromObject(PowiainaNum.fromNumber(Number(input)));
|
|
1397
|
+
return x;
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
input = replaceETo10(input);
|
|
1401
|
+
if (!isPowiainaNum.test(input)) {
|
|
1402
|
+
throw powiainaNumError + "malformed input: " + input;
|
|
1403
|
+
}
|
|
1404
|
+
var negateIt = false;
|
|
1405
|
+
var recipIt = false;
|
|
1406
|
+
if (input[0] == "-" || input[0] == "+") {
|
|
1407
|
+
var numSigns = input.search(/[^-\+]/);
|
|
1408
|
+
var signs = input.substring(0, numSigns);
|
|
1409
|
+
negateIt = ((_b = (_a = signs.match(/-/g)) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) % 2 == 1;
|
|
1410
|
+
input = input.substring(numSigns);
|
|
1411
|
+
}
|
|
1412
|
+
if (input[0] == "/") {
|
|
1413
|
+
var numSigns = input.search(/[^\/]/);
|
|
1414
|
+
var signs = input.substring(0, numSigns);
|
|
1415
|
+
recipIt = ((_d = (_c = signs.match(/\//g)) === null || _c === void 0 ? void 0 : _c.length) !== null && _d !== void 0 ? _d : 0) % 2 == 1;
|
|
1416
|
+
input = input.substring(numSigns);
|
|
1417
|
+
}
|
|
1418
|
+
if (input == "NaN")
|
|
1419
|
+
x.array = [newOperator(NaN)];
|
|
1420
|
+
else if (input == "Infinity")
|
|
1421
|
+
x.array = [newOperator(Infinity)];
|
|
1422
|
+
else {
|
|
1423
|
+
x.sign = 1;
|
|
1424
|
+
x.array = [newOperator(0)];
|
|
1425
|
+
var a, b, c, d, i;
|
|
1426
|
+
while (input) {
|
|
1427
|
+
if (/^(\(?10[\^\{])/.test(input)) {
|
|
1428
|
+
/*
|
|
1429
|
+
10^ - 匹配
|
|
1430
|
+
10{ - 匹配
|
|
1431
|
+
(10^ - 匹配
|
|
1432
|
+
(10{ - 匹配
|
|
1433
|
+
10x - 不匹配(最后一个字符不是 ^ 或 {)
|
|
1434
|
+
110^ - 不匹配(不是以 10 开头)
|
|
1435
|
+
*/
|
|
1436
|
+
if (input[0] == "(")
|
|
1437
|
+
input = input.substring(1);
|
|
1438
|
+
//cutted, 10^.... or 10{....
|
|
1439
|
+
var arrows, expans, megota;
|
|
1440
|
+
if (input[2] == "^") {
|
|
1441
|
+
a = input.substring(2).search(/[^\^]/);
|
|
1442
|
+
//cut input to ^^...^^, and search how numbers
|
|
1443
|
+
arrows = a;
|
|
1444
|
+
// 10^^^
|
|
1445
|
+
b = a + 2; // b points to after ^'s.
|
|
1446
|
+
}
|
|
1447
|
+
else {
|
|
1448
|
+
// 10{...}
|
|
1449
|
+
a = input.indexOf("}");
|
|
1450
|
+
// select contents between {...}
|
|
1451
|
+
let tmp = input.substring(3, a).split(",");
|
|
1452
|
+
arrows = Number(tmp[0] == "!" ? Infinity : tmp[0]);
|
|
1453
|
+
expans = Number((_e = (tmp[1] == "!" ? Infinity : tmp[1])) !== null && _e !== void 0 ? _e : 1);
|
|
1454
|
+
megota = Number((_f = tmp[2]) !== null && _f !== void 0 ? _f : 1);
|
|
1455
|
+
b = a + 1;
|
|
1456
|
+
// b points to after }.
|
|
1457
|
+
}
|
|
1458
|
+
input = input.substring(b);
|
|
1459
|
+
if (input[0] == ")") {
|
|
1460
|
+
// )^....<Space>
|
|
1461
|
+
a = input.indexOf(" ");
|
|
1462
|
+
c = Number(input.substring(2, a)); // Select contents between )^....<Space>
|
|
1463
|
+
input = input.substring(a + 1); // c points to after <Space>
|
|
1464
|
+
}
|
|
1465
|
+
else {
|
|
1466
|
+
c = 1; // There is only spaces, count as <ONE>
|
|
1467
|
+
}
|
|
1468
|
+
if (arrows == 1 && expans == 1 && megota == 1) {
|
|
1469
|
+
if (x.array.length >= 2 && x.array[1].arrow == 1) {
|
|
1470
|
+
x.array[1].repeat += c;
|
|
1471
|
+
}
|
|
1472
|
+
else {
|
|
1473
|
+
x.array.splice(1, 0, newOperator(c, 1, expans, megota));
|
|
1474
|
+
}
|
|
1475
|
+
}
|
|
1476
|
+
else if (arrows == 2 && expans == 1 && megota == 1) {
|
|
1477
|
+
a =
|
|
1478
|
+
x.array.length >= 2 && x.array[1].arrow == 1
|
|
1479
|
+
? x.array[1].repeat
|
|
1480
|
+
: 0;
|
|
1481
|
+
b = x.array[0].repeat;
|
|
1482
|
+
if (b >= 1e10)
|
|
1483
|
+
++a;
|
|
1484
|
+
if (b >= 10)
|
|
1485
|
+
++a;
|
|
1486
|
+
x.array[0].repeat = a;
|
|
1487
|
+
if (x.array.length >= 2 && x.array[1].arrow == 1)
|
|
1488
|
+
x.array.splice(1, 1);
|
|
1489
|
+
d = x.getOperatorIndex(2);
|
|
1490
|
+
if (Number.isInteger(d))
|
|
1491
|
+
x.array[d].repeat += c;
|
|
1492
|
+
else
|
|
1493
|
+
x.array.splice(Math.ceil(d), 0, newOperator(c, 2, expans, megota));
|
|
1494
|
+
}
|
|
1495
|
+
else if (isFinite(arrows)) {
|
|
1496
|
+
a = x.getOperator(arrows - 1);
|
|
1497
|
+
b = x.getOperator(arrows - 2);
|
|
1498
|
+
if (b >= 10)
|
|
1499
|
+
++a;
|
|
1500
|
+
d = x.getOperatorIndex(arrows);
|
|
1501
|
+
x.array.splice(1, Math.ceil(d) - 1);
|
|
1502
|
+
x.array[0].repeat = a;
|
|
1503
|
+
if (Number.isInteger(d))
|
|
1504
|
+
x.array[1].repeat += c;
|
|
1505
|
+
else
|
|
1506
|
+
x.array.splice(1, 0, newOperator(c, arrows, expans, megota));
|
|
1507
|
+
}
|
|
1508
|
+
else {
|
|
1509
|
+
x.array.splice(1, 0, newOperator(c, arrows, expans, megota));
|
|
1510
|
+
}
|
|
1511
|
+
}
|
|
1512
|
+
else {
|
|
1513
|
+
break;
|
|
1514
|
+
}
|
|
1515
|
+
}
|
|
1516
|
+
a = input.split(/[Ee]/);
|
|
1517
|
+
b = [x.array[0].repeat, 0];
|
|
1518
|
+
c = 1;
|
|
1519
|
+
for (let i = a.length - 1; i >= 0; --i) {
|
|
1520
|
+
//The things that are already there
|
|
1521
|
+
if (b[0] < MSI_LOG10 && b[1] === 0) {
|
|
1522
|
+
b[0] = Math.pow(10, c * b[0]);
|
|
1523
|
+
}
|
|
1524
|
+
else if (c == -1) {
|
|
1525
|
+
if (b[1] === 0) {
|
|
1526
|
+
b[0] = Math.pow(10, c * b[0]);
|
|
1527
|
+
}
|
|
1528
|
+
else if (b[1] == 1 && b[0] <= Math.log10(Number.MAX_VALUE)) {
|
|
1529
|
+
b[0] = Math.pow(10, c * Math.pow(10, b[0]));
|
|
1530
|
+
}
|
|
1531
|
+
else {
|
|
1532
|
+
b[0] = 0;
|
|
1533
|
+
}
|
|
1534
|
+
b[1] = 0;
|
|
1535
|
+
}
|
|
1536
|
+
else {
|
|
1537
|
+
b[1]++;
|
|
1538
|
+
}
|
|
1539
|
+
//Multiplying coefficient
|
|
1540
|
+
var decimalPointPos = a[i].indexOf(".");
|
|
1541
|
+
var intPartLen = decimalPointPos == -1 ? a[i].length : decimalPointPos;
|
|
1542
|
+
if (b[1] === 0) {
|
|
1543
|
+
if (intPartLen >= LONG_STRING_MIN_LENGTH)
|
|
1544
|
+
((b[0] =
|
|
1545
|
+
Math.log10(b[0]) +
|
|
1546
|
+
log10LongString(a[i].substring(0, intPartLen))),
|
|
1547
|
+
(b[1] = 1));
|
|
1548
|
+
else if (a[i])
|
|
1549
|
+
b[0] *= Number(a[i]);
|
|
1550
|
+
}
|
|
1551
|
+
else {
|
|
1552
|
+
d =
|
|
1553
|
+
intPartLen >= LONG_STRING_MIN_LENGTH
|
|
1554
|
+
? log10LongString(a[i].substring(0, intPartLen))
|
|
1555
|
+
: a[i]
|
|
1556
|
+
? Math.log10(Number(a[i]))
|
|
1557
|
+
: 0;
|
|
1558
|
+
if (b[1] == 1) {
|
|
1559
|
+
b[0] += d;
|
|
1560
|
+
}
|
|
1561
|
+
else if (b[1] == 2 && b[0] < MSI_LOG10 + Math.log10(d)) {
|
|
1562
|
+
b[0] += Math.log10(1 + Math.pow(10, Math.log10(d) - b[0]));
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
//Carrying
|
|
1566
|
+
if (b[0] < MSI_LOG10 && b[1]) {
|
|
1567
|
+
b[0] = Math.pow(10, b[0]);
|
|
1568
|
+
b[1]--;
|
|
1569
|
+
}
|
|
1570
|
+
else if (b[0] > MSI) {
|
|
1571
|
+
b[0] = Math.log10(b[0]);
|
|
1572
|
+
b[1]++;
|
|
1573
|
+
}
|
|
1574
|
+
}
|
|
1575
|
+
x.array[0].repeat = b[0];
|
|
1576
|
+
if (b[1]) {
|
|
1577
|
+
if (x.array.length >= 2 && x.array[1].arrow == 1)
|
|
1578
|
+
x.array[1].repeat += b[1];
|
|
1579
|
+
else
|
|
1580
|
+
x.array.splice(1, 0, newOperator(b[1], 1, 1, 1));
|
|
1581
|
+
}
|
|
1582
|
+
}
|
|
1583
|
+
if (negateIt)
|
|
1584
|
+
x.sign *= -1;
|
|
1585
|
+
if (recipIt)
|
|
1586
|
+
x.small = !x.small;
|
|
1587
|
+
x.normalize();
|
|
1588
|
+
x.normalize();
|
|
1589
|
+
return x;
|
|
1590
|
+
}
|
|
1591
|
+
static fromObject(powlikeObject) {
|
|
1592
|
+
let obj = new PowiainaNum();
|
|
1593
|
+
obj.array = [];
|
|
1594
|
+
if (isExpantaNumArray(powlikeObject)) {
|
|
1595
|
+
for (let i = 0; i < powlikeObject.length; i++) {
|
|
1596
|
+
obj.array[i] = {
|
|
1597
|
+
arrow: powlikeObject[i][0],
|
|
1598
|
+
expans: 1,
|
|
1599
|
+
megota: 1,
|
|
1600
|
+
repeat: powlikeObject[i][1]
|
|
1601
|
+
};
|
|
1602
|
+
}
|
|
1603
|
+
obj.small = false;
|
|
1604
|
+
obj.sign = 1;
|
|
1605
|
+
obj.layer = 0;
|
|
1606
|
+
obj.normalize();
|
|
1607
|
+
return obj;
|
|
1608
|
+
}
|
|
1609
|
+
else {
|
|
1610
|
+
for (let i = 0; i < powlikeObject.array.length; i++) {
|
|
1611
|
+
obj.array[i] = {
|
|
1612
|
+
arrow: powlikeObject.array[i].arrow,
|
|
1613
|
+
expans: powlikeObject.array[i].expans,
|
|
1614
|
+
megota: powlikeObject.array[i].megota,
|
|
1615
|
+
repeat: powlikeObject.array[i].repeat,
|
|
1616
|
+
valuereplaced: powlikeObject.array[i].valuereplaced,
|
|
1617
|
+
};
|
|
1618
|
+
}
|
|
1619
|
+
obj.small = powlikeObject.small;
|
|
1620
|
+
obj.sign = powlikeObject.sign;
|
|
1621
|
+
obj.layer = powlikeObject.layer;
|
|
1622
|
+
return obj;
|
|
1623
|
+
}
|
|
1624
|
+
}
|
|
1625
|
+
/**
|
|
1626
|
+
* A property arary value for version 0.1.x PowiainaNum.
|
|
1627
|
+
*/
|
|
1628
|
+
get arr01() {
|
|
1629
|
+
let res = [0];
|
|
1630
|
+
for (let i = 0; i < this.array.length; i++) {
|
|
1631
|
+
if (i == 0)
|
|
1632
|
+
res[0] = this.array[i].repeat;
|
|
1633
|
+
else {
|
|
1634
|
+
// @ts-ignore
|
|
1635
|
+
res[i] = [0, 0, 0, 0];
|
|
1636
|
+
// @ts-ignore
|
|
1637
|
+
res[i][0] = this.array[i].arrow == Infinity ? "x" : this.array[i].arrow;
|
|
1638
|
+
// @ts-ignore
|
|
1639
|
+
res[i][1] = this.array[i].repeat;
|
|
1640
|
+
// @ts-ignore
|
|
1641
|
+
res[i][2] = this.array[i].expans == Infinity ? "x" : this.array[i].expans;
|
|
1642
|
+
// @ts-ignore
|
|
1643
|
+
res[i][3] = this.array[i].megota;
|
|
1644
|
+
}
|
|
1645
|
+
}
|
|
1646
|
+
return res;
|
|
1647
|
+
}
|
|
1648
|
+
}
|
|
1649
|
+
PowiainaNum.ZERO = new PowiainaNum({
|
|
1650
|
+
array: [
|
|
1651
|
+
{
|
|
1652
|
+
arrow: 0,
|
|
1653
|
+
expans: 1,
|
|
1654
|
+
megota: 1,
|
|
1655
|
+
repeat: Infinity,
|
|
1656
|
+
},
|
|
1657
|
+
],
|
|
1658
|
+
small: true,
|
|
1659
|
+
layer: 0,
|
|
1660
|
+
sign: 0,
|
|
1661
|
+
});
|
|
1662
|
+
PowiainaNum.ONE = new PowiainaNum({
|
|
1663
|
+
array: [
|
|
1664
|
+
{
|
|
1665
|
+
arrow: 0,
|
|
1666
|
+
expans: 1,
|
|
1667
|
+
megota: 1,
|
|
1668
|
+
repeat: 1,
|
|
1669
|
+
},
|
|
1670
|
+
],
|
|
1671
|
+
small: false,
|
|
1672
|
+
layer: 0,
|
|
1673
|
+
sign: 1,
|
|
1674
|
+
});
|
|
1675
|
+
PowiainaNum.MSI = new PowiainaNum(MSI);
|
|
1676
|
+
PowiainaNum.MSI_REC = (function () {
|
|
1677
|
+
let obj = new PowiainaNum(MSI);
|
|
1678
|
+
obj.small = true;
|
|
1679
|
+
return obj;
|
|
1680
|
+
})();
|
|
1681
|
+
PowiainaNum.E_MSI = new PowiainaNum({
|
|
1682
|
+
array: [
|
|
1683
|
+
{
|
|
1684
|
+
arrow: 0,
|
|
1685
|
+
expans: 1,
|
|
1686
|
+
megota: 1,
|
|
1687
|
+
repeat: MSI,
|
|
1688
|
+
},
|
|
1689
|
+
{ arrow: 1, expans: 1, megota: 1, repeat: 1 },
|
|
1690
|
+
],
|
|
1691
|
+
small: false,
|
|
1692
|
+
layer: 0,
|
|
1693
|
+
sign: 1,
|
|
1694
|
+
});
|
|
1695
|
+
PowiainaNum.E_MSI_REC = new PowiainaNum({
|
|
1696
|
+
array: [
|
|
1697
|
+
{
|
|
1698
|
+
arrow: 0,
|
|
1699
|
+
expans: 1,
|
|
1700
|
+
megota: 1,
|
|
1701
|
+
repeat: MSI,
|
|
1702
|
+
},
|
|
1703
|
+
{ arrow: 1, expans: 1, megota: 1, repeat: 1 },
|
|
1704
|
+
],
|
|
1705
|
+
small: true,
|
|
1706
|
+
layer: 0,
|
|
1707
|
+
sign: 1,
|
|
1708
|
+
});
|
|
1709
|
+
PowiainaNum.TETRATED_MSI = new PowiainaNum({
|
|
1710
|
+
array: [
|
|
1711
|
+
{
|
|
1712
|
+
arrow: 0,
|
|
1713
|
+
expans: 1,
|
|
1714
|
+
megota: 1,
|
|
1715
|
+
repeat: MSI,
|
|
1716
|
+
},
|
|
1717
|
+
{ arrow: 1, expans: 1, megota: 1, repeat: MSI },
|
|
1718
|
+
],
|
|
1719
|
+
small: false,
|
|
1720
|
+
layer: 0,
|
|
1721
|
+
sign: 1,
|
|
1722
|
+
});
|
|
1723
|
+
PowiainaNum.PENTATED_MSI = new PowiainaNum({
|
|
1724
|
+
array: [
|
|
1725
|
+
{
|
|
1726
|
+
arrow: 0,
|
|
1727
|
+
expans: 1,
|
|
1728
|
+
megota: 1,
|
|
1729
|
+
repeat: MSI,
|
|
1730
|
+
},
|
|
1731
|
+
{ arrow: 1, expans: 1, megota: 1, repeat: MSI },
|
|
1732
|
+
{ arrow: 2, expans: 1, megota: 1, repeat: MSI },
|
|
1733
|
+
],
|
|
1734
|
+
small: false,
|
|
1735
|
+
layer: 0,
|
|
1736
|
+
sign: 1,
|
|
1737
|
+
});
|
|
1738
|
+
PowiainaNum.TRITRI = new PowiainaNum({
|
|
1739
|
+
small: false, layer: 0, sign: 1,
|
|
1740
|
+
array: [
|
|
1741
|
+
newOperator(3638334640023.7783, 0, 1, 1),
|
|
1742
|
+
newOperator(7625587484984, 1, 1, 1)
|
|
1743
|
+
]
|
|
1744
|
+
});
|
|
1745
|
+
PowiainaNum.GRAHAMS_NUMBER = new PowiainaNum("(10{!})^63 10^^^(10^)^7625597484984 3638334640023.7783");
|
|
1746
|
+
PowiainaNum.POSITIVE_INFINITY = new PowiainaNum(Infinity);
|
|
1747
|
+
PowiainaNum.NEGATIVE_INFINITY = new PowiainaNum(-Infinity);
|
|
1748
|
+
PowiainaNum.NaN = new PowiainaNum({
|
|
1749
|
+
array: [
|
|
1750
|
+
{
|
|
1751
|
+
arrow: 0,
|
|
1752
|
+
expans: 1,
|
|
1753
|
+
megota: 1,
|
|
1754
|
+
repeat: NaN,
|
|
1755
|
+
},
|
|
1756
|
+
],
|
|
1757
|
+
small: false,
|
|
1758
|
+
layer: 0,
|
|
1759
|
+
sign: 0,
|
|
1760
|
+
});
|
|
1761
|
+
PowiainaNum.maxOps = 100;
|
|
1762
|
+
export default PowiainaNum;
|