@numio/bigmath 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +129 -0
- package/build.ts +45 -0
- package/index.ts +6 -0
- package/npm/LICENSE +21 -0
- package/npm/README.md +129 -0
- package/npm/index.d.ts +5 -0
- package/npm/index.js +5 -0
- package/npm/package-lock.json +16 -0
- package/npm/package.json +57 -0
- package/npm/src/add/index.d.ts +2 -0
- package/npm/src/add/index.js +19 -0
- package/npm/src/add/types.d.ts +2 -0
- package/npm/src/add/utils.d.ts +3 -0
- package/npm/src/add/utils.js +48 -0
- package/npm/src/div/index.d.ts +2 -0
- package/npm/src/div/index.js +15 -0
- package/npm/src/div/types.d.ts +2 -0
- package/npm/src/div/utils.d.ts +2 -0
- package/npm/src/div/utils.js +90 -0
- package/npm/src/mul/index.d.ts +2 -0
- package/npm/src/mul/index.js +12 -0
- package/npm/src/mul/types.d.ts +2 -0
- package/npm/src/mul/utils.d.ts +3 -0
- package/npm/src/mul/utils.js +42 -0
- package/npm/src/shared/types.d.ts +4 -0
- package/npm/src/shared/utils.d.ts +5 -0
- package/npm/src/shared/utils.js +108 -0
- package/npm/src/sub/index.d.ts +2 -0
- package/npm/src/sub/index.js +19 -0
- package/npm/src/sub/types.d.ts +2 -0
- package/npm/src/sub/utils.d.ts +3 -0
- package/npm/src/sub/utils.js +76 -0
- package/npm/src/types.d.ts +6 -0
- package/package.json +57 -0
- package/src/add/index.ts +34 -0
- package/src/add/types.ts +7 -0
- package/src/add/utils.ts +54 -0
- package/src/div/index.ts +26 -0
- package/src/div/types.ts +8 -0
- package/src/div/utils.ts +110 -0
- package/src/mul/index.ts +23 -0
- package/src/mul/types.ts +7 -0
- package/src/mul/utils.ts +56 -0
- package/src/shared/types.ts +16 -0
- package/src/shared/utils.ts +130 -0
- package/src/sub/index.ts +35 -0
- package/src/sub/types.ts +6 -0
- package/src/sub/utils.ts +86 -0
- package/src/types.ts +6 -0
- package/tsconfig.json +9 -0
@@ -0,0 +1,42 @@
|
|
1
|
+
/** This function multiplies 2 numbers (as array). */
|
2
|
+
export var multiplication = function (_a, _b, isNegative) {
|
3
|
+
var _c, _d;
|
4
|
+
var arrL = _a[0], intL = _a[1];
|
5
|
+
var arrR = _b[0], intR = _b[1];
|
6
|
+
if (arrL.length === 0 || arrR.length === 0 ||
|
7
|
+
(arrL.length === 1 && arrL[0] === 48) ||
|
8
|
+
(arrR.length === 1 && arrR[0] === 48)) {
|
9
|
+
return { array: [48], intLength: 1, isFloat: false, isNegative: false };
|
10
|
+
}
|
11
|
+
var dec = (arrL.length - intL) + (arrR.length - intR);
|
12
|
+
var _e = arrL.length >= arrR.length
|
13
|
+
? [arrL, arrR]
|
14
|
+
: [arrR, arrL], left = _e[0], right = _e[1];
|
15
|
+
var sums = Array(right.length + left.length - 1);
|
16
|
+
for (var i = right.length - 1; i >= 0; i--) {
|
17
|
+
for (var j = left.length - 1; j >= 0; j--) {
|
18
|
+
var idx_1 = j + i;
|
19
|
+
sums[idx_1] = ((_c = sums[idx_1]) !== null && _c !== void 0 ? _c : 0) +
|
20
|
+
(left[j] - 48) * (right[i] - 48);
|
21
|
+
}
|
22
|
+
}
|
23
|
+
var result = Array(sums.length);
|
24
|
+
var idx = sums.length - 1;
|
25
|
+
var carryOver = 0;
|
26
|
+
var currNum = 0;
|
27
|
+
var nextNum = 0;
|
28
|
+
while (idx >= 0) {
|
29
|
+
currNum = (_d = sums[idx]) !== null && _d !== void 0 ? _d : 0;
|
30
|
+
nextNum = (currNum + carryOver) % 10;
|
31
|
+
carryOver = (carryOver + currNum) / 10 | 0;
|
32
|
+
result[idx] = nextNum + 48;
|
33
|
+
idx -= 1;
|
34
|
+
}
|
35
|
+
carryOver > 0 && result.unshift(carryOver + 48);
|
36
|
+
return {
|
37
|
+
array: result,
|
38
|
+
intLength: result.length - dec,
|
39
|
+
isFloat: dec > 0,
|
40
|
+
isNegative: isNegative,
|
41
|
+
};
|
42
|
+
};
|
@@ -0,0 +1,108 @@
|
|
1
|
+
// array to string
|
2
|
+
export var a2sMD = function (array, isFloat, isNegative, intLength) {
|
3
|
+
if (isNegative === void 0) { isNegative = false; }
|
4
|
+
if (intLength === void 0) { intLength = 0; }
|
5
|
+
var result = [];
|
6
|
+
var lastValuableIdx = array.length;
|
7
|
+
if (isFloat) {
|
8
|
+
var idx = array.length - 1;
|
9
|
+
while (array[idx] === 48 && idx >= intLength) {
|
10
|
+
lastValuableIdx = idx;
|
11
|
+
idx -= 1;
|
12
|
+
}
|
13
|
+
}
|
14
|
+
if (intLength !== array.length) {
|
15
|
+
if (intLength <= 0) {
|
16
|
+
result.push(48, 46);
|
17
|
+
for (var i = intLength; i < 0; i++) {
|
18
|
+
result.push(48);
|
19
|
+
}
|
20
|
+
for (var i = 0; i < lastValuableIdx; i++) {
|
21
|
+
result.push(array[i]);
|
22
|
+
}
|
23
|
+
}
|
24
|
+
else {
|
25
|
+
for (var i = 0; i < lastValuableIdx; i++) {
|
26
|
+
if (i === intLength)
|
27
|
+
result.push(46);
|
28
|
+
result.push(array[i]);
|
29
|
+
}
|
30
|
+
}
|
31
|
+
return (isNegative ? "-" : "") + String.fromCharCode.apply(String, result);
|
32
|
+
}
|
33
|
+
return (isNegative ? "-" : "") + String.fromCharCode.apply(String, array).trim();
|
34
|
+
};
|
35
|
+
export var a2sSA = function (array, isFloat, isNegative) {
|
36
|
+
if (isNegative === void 0) { isNegative = false; }
|
37
|
+
var isToCheckTail = isFloat;
|
38
|
+
for (var i = array.length - 1; i >= 0; i--) {
|
39
|
+
if (isToCheckTail && array[i] === 46) {
|
40
|
+
array[i] = 32;
|
41
|
+
isToCheckTail = false;
|
42
|
+
break;
|
43
|
+
}
|
44
|
+
if (isToCheckTail && array[i] === 48)
|
45
|
+
array[i] = 32;
|
46
|
+
else
|
47
|
+
break;
|
48
|
+
}
|
49
|
+
for (var i = 0; i < array.length; i++) {
|
50
|
+
if (array[i + 1] === 46 || array.length <= 1)
|
51
|
+
break;
|
52
|
+
if (array[i] === 48)
|
53
|
+
array[i] = 32;
|
54
|
+
else
|
55
|
+
break;
|
56
|
+
}
|
57
|
+
return (isNegative ? "-" : "") + String.fromCharCode.apply(String, array).trim();
|
58
|
+
};
|
59
|
+
// string to array (sub, add)
|
60
|
+
export var s2aSA = function (string) {
|
61
|
+
var isNegative = string.charCodeAt(0) === 45;
|
62
|
+
var shift = isNegative ? 1 : 0;
|
63
|
+
var array = Array(string.length - shift);
|
64
|
+
var intLength = string.length - shift;
|
65
|
+
var isFloat = false;
|
66
|
+
for (var idx = 0 + shift; idx < string.length; idx++) {
|
67
|
+
var charCode = string.charCodeAt(idx);
|
68
|
+
if (charCode === 46) {
|
69
|
+
intLength = idx - shift;
|
70
|
+
isFloat || (isFloat = true);
|
71
|
+
}
|
72
|
+
array[idx - shift] = charCode;
|
73
|
+
}
|
74
|
+
return { array: array, intLength: intLength, isNegative: isNegative, isFloat: isFloat };
|
75
|
+
};
|
76
|
+
// string to array (mul, div)
|
77
|
+
export var s2aMD = function (string) {
|
78
|
+
var array = Array(0);
|
79
|
+
var isNegative = string.charCodeAt(0) === 45;
|
80
|
+
var shift = isNegative ? 1 : 0;
|
81
|
+
var dec = 0;
|
82
|
+
if ((string.length === 1 && string.charCodeAt(0) === 48) ||
|
83
|
+
string.length === 2 && string.charCodeAt(0) === 45 &&
|
84
|
+
string.charCodeAt(1) === 48) {
|
85
|
+
return {
|
86
|
+
array: [48],
|
87
|
+
intLength: 1,
|
88
|
+
isNegative: false,
|
89
|
+
isFloat: false,
|
90
|
+
};
|
91
|
+
}
|
92
|
+
for (var idx = 0 + shift; idx < string.length; idx++) {
|
93
|
+
var charCode = string.charCodeAt(idx);
|
94
|
+
if (array.length === 0 && charCode === 48)
|
95
|
+
continue;
|
96
|
+
if (charCode === 46) {
|
97
|
+
dec = string.length - 1 - idx;
|
98
|
+
continue;
|
99
|
+
}
|
100
|
+
array.push(charCode);
|
101
|
+
}
|
102
|
+
return {
|
103
|
+
array: array,
|
104
|
+
intLength: array.length - dec,
|
105
|
+
isNegative: isNegative,
|
106
|
+
isFloat: dec > 0,
|
107
|
+
};
|
108
|
+
};
|
@@ -0,0 +1,19 @@
|
|
1
|
+
import { addition } from "../add/utils.js";
|
2
|
+
import { a2sSA, s2aSA } from "../shared/utils.js";
|
3
|
+
import { subtract } from "./utils.js";
|
4
|
+
/** This function subtracts 2 numbers (as string). */
|
5
|
+
export function sub(strs) {
|
6
|
+
var arrays = strs.map(function (str) { return s2aSA(str); });
|
7
|
+
var inputData = arrays.reduce(function (left, right) {
|
8
|
+
if (left.array.length === 0)
|
9
|
+
return right;
|
10
|
+
if (left.isNegative && right.isNegative) {
|
11
|
+
return subtract([right.array, right.intLength], [left.array, left.intLength]);
|
12
|
+
}
|
13
|
+
if (!left.isNegative && !right.isNegative) {
|
14
|
+
return subtract([left.array, left.intLength], [right.array, right.intLength]);
|
15
|
+
}
|
16
|
+
return addition([left.array, left.intLength], [right.array, right.intLength], left.isNegative);
|
17
|
+
}, { array: [], intLength: 0, isNegative: false, isFloat: false });
|
18
|
+
return a2sSA(inputData.array, inputData.isFloat, inputData.isNegative);
|
19
|
+
}
|
@@ -0,0 +1,76 @@
|
|
1
|
+
/** This function subtracts 2 numbers (as array). */
|
2
|
+
export var subtract = function (_a, _b) {
|
3
|
+
var _c, _d;
|
4
|
+
var _e, _f;
|
5
|
+
var arrL = _a[0], intL = _a[1];
|
6
|
+
var arrR = _b[0], intR = _b[1];
|
7
|
+
var lenDiff = (intL - intR) * (intL > intR ? 1 : -1);
|
8
|
+
var _g = intL >= intR
|
9
|
+
? [arrL, arrR, intL, intR]
|
10
|
+
: [arrR, arrL, intR, intL], left = _g[0], right = _g[1], intLeft = _g[2], intRight = _g[3];
|
11
|
+
var fracLenL = left.length - intLeft;
|
12
|
+
var fracLenR = right.length - intRight;
|
13
|
+
var pl = lenDiff;
|
14
|
+
var pr = 0;
|
15
|
+
var isLeftBigger = lenDiff > 0;
|
16
|
+
var carryOver = false;
|
17
|
+
var isNegative = intLeft !== intL;
|
18
|
+
if (intLeft === left.length && intRight !== right.length)
|
19
|
+
left.push(46);
|
20
|
+
if (intRight === right.length && intLeft !== left.length)
|
21
|
+
right.push(46);
|
22
|
+
while (pr < right.length) {
|
23
|
+
if (left[pl] === 46 || right[pr] === 46) {
|
24
|
+
pr += 1;
|
25
|
+
pl += 1;
|
26
|
+
}
|
27
|
+
var sub = (((_e = left[pl]) !== null && _e !== void 0 ? _e : 48) - ((_f = right[pr]) !== null && _f !== void 0 ? _f : 48)) + 48;
|
28
|
+
if (!isLeftBigger && left[pl] > right[pr]) {
|
29
|
+
isLeftBigger = true;
|
30
|
+
}
|
31
|
+
if (!isLeftBigger && sub < 48 && lenDiff === 0) {
|
32
|
+
_c = [right, left], left = _c[0], right = _c[1];
|
33
|
+
_d = [intR, intL], intL = _d[0], intR = _d[1];
|
34
|
+
isLeftBigger = true;
|
35
|
+
isNegative = true;
|
36
|
+
continue;
|
37
|
+
}
|
38
|
+
if (sub < 48) {
|
39
|
+
sub += 10;
|
40
|
+
carryOver = true;
|
41
|
+
}
|
42
|
+
var plReverse = pl - 1;
|
43
|
+
var prReverse = pr - 1;
|
44
|
+
while (carryOver) {
|
45
|
+
if (left[plReverse] === 46 || right[prReverse] === 46) {
|
46
|
+
plReverse -= 1;
|
47
|
+
prReverse -= 1;
|
48
|
+
}
|
49
|
+
if (left[plReverse] !== 48) {
|
50
|
+
plReverse >= 0 && (left[plReverse] -= 1);
|
51
|
+
prReverse >= 0 && (right[prReverse] -= 1);
|
52
|
+
carryOver = false;
|
53
|
+
}
|
54
|
+
else {
|
55
|
+
plReverse >= 0 && (left[plReverse] = 57);
|
56
|
+
prReverse >= 0 && (right[prReverse] = 57);
|
57
|
+
}
|
58
|
+
plReverse -= 1;
|
59
|
+
prReverse -= 1;
|
60
|
+
}
|
61
|
+
left[pl] = sub;
|
62
|
+
right[pr] = sub;
|
63
|
+
pl += 1;
|
64
|
+
pr += 1;
|
65
|
+
}
|
66
|
+
while (left[0] === 48 && left[1] !== 46 && left.length > 1) {
|
67
|
+
left.shift();
|
68
|
+
intLeft -= 1;
|
69
|
+
}
|
70
|
+
return {
|
71
|
+
array: left,
|
72
|
+
intLength: intLeft,
|
73
|
+
isNegative: isNegative,
|
74
|
+
isFloat: fracLenL + fracLenR > 0,
|
75
|
+
};
|
76
|
+
};
|
package/package.json
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
{
|
2
|
+
"name": "@numio/bigmath",
|
3
|
+
"description": "@numio/bigmath is an arbitrary-precision arithmetic library. It can be used for basic operations with decimal numbers (integers and float)",
|
4
|
+
"version": "1.0.1",
|
5
|
+
"keywords": [
|
6
|
+
"precision",
|
7
|
+
"arithmetic",
|
8
|
+
"big",
|
9
|
+
"number",
|
10
|
+
"decimal",
|
11
|
+
"float",
|
12
|
+
"biginteger",
|
13
|
+
"bigdecimal",
|
14
|
+
"bignumber",
|
15
|
+
"bigint",
|
16
|
+
"bignum",
|
17
|
+
"infinite",
|
18
|
+
"longnumbers",
|
19
|
+
"infinitenumbers",
|
20
|
+
"integer",
|
21
|
+
"float",
|
22
|
+
"math",
|
23
|
+
"add",
|
24
|
+
"multiply",
|
25
|
+
"subtract",
|
26
|
+
"plus",
|
27
|
+
"minus",
|
28
|
+
"divide",
|
29
|
+
"long division",
|
30
|
+
"bigmath",
|
31
|
+
"numio"
|
32
|
+
],
|
33
|
+
"repository": {
|
34
|
+
"type": "git",
|
35
|
+
"url": "git+https://github.com/shpunter/numio-bigmath.git"
|
36
|
+
},
|
37
|
+
"main": "./index.js",
|
38
|
+
"types": "./index.d.ts",
|
39
|
+
"exports": {
|
40
|
+
".": {
|
41
|
+
"import": "./index.js"
|
42
|
+
},
|
43
|
+
"./package.json": "./package.json"
|
44
|
+
},
|
45
|
+
"author": {
|
46
|
+
"name": "Oleksandr Brudnovskyi ",
|
47
|
+
"email": "oleksandr.brudnovskyi@gmail.com"
|
48
|
+
},
|
49
|
+
"engines": {
|
50
|
+
"node": "*"
|
51
|
+
},
|
52
|
+
"license": "MIT",
|
53
|
+
"scripts": {
|
54
|
+
"test": "node test"
|
55
|
+
},
|
56
|
+
"dependencies": {}
|
57
|
+
}
|
package/src/add/index.ts
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
import { a2sSA, s2aSA } from "../shared/utils.ts";
|
2
|
+
import { subtract } from "../sub/utils.ts";
|
3
|
+
import { addition } from "./utils.ts";
|
4
|
+
|
5
|
+
/** This function adds 2 numbers (as string). */
|
6
|
+
export function add(strs: string[]): string {
|
7
|
+
const arrays = strs.map((str) => s2aSA(str));
|
8
|
+
|
9
|
+
const inputData = arrays.reduce((left, right) => {
|
10
|
+
if (left.array.length === 0) return right;
|
11
|
+
|
12
|
+
if (left.isNegative && !right.isNegative) {
|
13
|
+
return subtract(
|
14
|
+
[right.array, right.intLength],
|
15
|
+
[left.array, left.intLength],
|
16
|
+
);
|
17
|
+
}
|
18
|
+
|
19
|
+
if (!left.isNegative && right.isNegative) {
|
20
|
+
return subtract(
|
21
|
+
[left.array, left.intLength],
|
22
|
+
[right.array, right.intLength],
|
23
|
+
);
|
24
|
+
}
|
25
|
+
|
26
|
+
return addition(
|
27
|
+
[left.array, left.intLength],
|
28
|
+
[right.array, right.intLength],
|
29
|
+
left.isNegative && right.isNegative,
|
30
|
+
);
|
31
|
+
}, { array: [], intLength: 0, isFloat: false, isNegative: false });
|
32
|
+
|
33
|
+
return a2sSA(inputData.array, inputData.isFloat, inputData.isNegative);
|
34
|
+
}
|
package/src/add/types.ts
ADDED
package/src/add/utils.ts
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
import type { Addition } from "./types.ts";
|
2
|
+
|
3
|
+
/** This function adds 2 numbers (as array). */
|
4
|
+
export const addition: Addition = ([arrL, intL], [arrR, intR], isNegative) => {
|
5
|
+
const [left, right, intLeft, intRight] = intL >= intR
|
6
|
+
? [arrL, arrR, intL, intR]
|
7
|
+
: [arrR, arrL, intR, intL];
|
8
|
+
const fracLenL = left.length - intLeft;
|
9
|
+
const fracLenR = right.length - intRight;
|
10
|
+
const fracMaxLen = (fracLenL >= fracLenR ? fracLenL : fracLenR) - 1;
|
11
|
+
let pl = (intLeft >= intRight ? intLeft : intRight) + fracMaxLen;
|
12
|
+
let pr = (intLeft >= intRight ? intRight : intLeft) + fracMaxLen;
|
13
|
+
let carryOver = 48;
|
14
|
+
|
15
|
+
if (fracLenL === 0 && fracLenR > 0) left.push(46);
|
16
|
+
|
17
|
+
while (pr >= 0) {
|
18
|
+
if (left[pl] === 46 || right[pr] === 46) {
|
19
|
+
pr -= 1;
|
20
|
+
pl -= 1;
|
21
|
+
}
|
22
|
+
|
23
|
+
const sum = ((left[pl] ?? 48) + (right[pr] ?? 48) + carryOver) -
|
24
|
+
3 * 48;
|
25
|
+
|
26
|
+
if (sum > 9) {
|
27
|
+
left[pl] = (sum % 10) + 48;
|
28
|
+
carryOver = ((sum / 10) | 0) + 48;
|
29
|
+
} else {
|
30
|
+
left[pl] = sum + 48;
|
31
|
+
carryOver = 48;
|
32
|
+
}
|
33
|
+
|
34
|
+
pr -= 1;
|
35
|
+
pl -= 1;
|
36
|
+
}
|
37
|
+
|
38
|
+
while (pl >= 0 && carryOver) {
|
39
|
+
const sum = (left[pl] + carryOver) - 2 * 48;
|
40
|
+
|
41
|
+
left[pl] = (sum % 10) + 48;
|
42
|
+
carryOver = ((sum / 10) | 0) + 48;
|
43
|
+
pl -= 1;
|
44
|
+
}
|
45
|
+
|
46
|
+
carryOver > 48 && left.unshift(carryOver);
|
47
|
+
|
48
|
+
return {
|
49
|
+
array: left,
|
50
|
+
intLength: left.length -1 - fracMaxLen,
|
51
|
+
isNegative,
|
52
|
+
isFloat: fracLenL + fracLenR > 0,
|
53
|
+
};
|
54
|
+
};
|
package/src/div/index.ts
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
import { a2sMD, s2aMD } from "../shared/utils.ts";
|
2
|
+
import { division } from "./utils.ts";
|
3
|
+
|
4
|
+
/** This function should divide 2 numbers (as string). */
|
5
|
+
export const div = (strs: string[], limit = 20): string => {
|
6
|
+
if (strs[0] === "0") return strs[0];
|
7
|
+
|
8
|
+
const arrays = strs.map((str) => s2aMD(str));
|
9
|
+
const inputData = arrays.reduce((left, right) => {
|
10
|
+
if (left.array.length === 0) return right;
|
11
|
+
|
12
|
+
return division(
|
13
|
+
[left.array, left.intLength],
|
14
|
+
[right.array, right.intLength],
|
15
|
+
left.isNegative !== right.isNegative,
|
16
|
+
limit
|
17
|
+
);
|
18
|
+
}, { array: [], intLength: 0, isNegative: false, isFloat: false });
|
19
|
+
|
20
|
+
return a2sMD(
|
21
|
+
inputData.array,
|
22
|
+
inputData.intLength != inputData.array.length,
|
23
|
+
inputData.isNegative,
|
24
|
+
inputData.intLength,
|
25
|
+
);
|
26
|
+
};
|
package/src/div/types.ts
ADDED
package/src/div/utils.ts
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
import type { Division } from "./types.ts";
|
2
|
+
|
3
|
+
export const division: Division = (
|
4
|
+
[arrL, intL],
|
5
|
+
[arrR, intR],
|
6
|
+
isNegative,
|
7
|
+
initLimit,
|
8
|
+
) => {
|
9
|
+
const decDiff = (arrL.length - intL) - (arrR.length - intR);
|
10
|
+
const [L, R] = [[arrR, 1], [arrL, -1]] as const;
|
11
|
+
const [arr, abs] = decDiff > 0 ? L : R;
|
12
|
+
|
13
|
+
for (let i = 0; i < decDiff * abs; i++) {
|
14
|
+
arr.push(48);
|
15
|
+
}
|
16
|
+
|
17
|
+
let digit = 48;
|
18
|
+
let limit = initLimit;
|
19
|
+
let isFloat = false;
|
20
|
+
let l = 0;
|
21
|
+
let r = arrR.length - 1;
|
22
|
+
let intLength = 0;
|
23
|
+
const result: number[] = [];
|
24
|
+
const lenArrayL = r - arrL.length;
|
25
|
+
|
26
|
+
for (let i = 0; i <= lenArrayL; i++) {
|
27
|
+
if (i === 0) {
|
28
|
+
isFloat = true;
|
29
|
+
intLength = 1;
|
30
|
+
}
|
31
|
+
|
32
|
+
result.push(48);
|
33
|
+
arrL.push(48);
|
34
|
+
limit -= 1;
|
35
|
+
}
|
36
|
+
|
37
|
+
while (r < arrL.length && limit >= 0) {
|
38
|
+
let comp = false;
|
39
|
+
|
40
|
+
if (arrL[l] === 48) l += 1;
|
41
|
+
|
42
|
+
for (let i = 0; i < arrR.length; i++) {
|
43
|
+
if ((r - l + 1) < arrR.length) comp = true;
|
44
|
+
if ((r - l + 1) !== arrR.length) break;
|
45
|
+
|
46
|
+
if (arrL[l + i] !== arrR[i]) {
|
47
|
+
comp = arrL[l + i] < arrR[i];
|
48
|
+
break;
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
if (comp) {
|
53
|
+
if (r < arrL.length && (result.length > 0 || digit !== 48)) {
|
54
|
+
if (!isFloat) intLength += 1;
|
55
|
+
result.push(digit);
|
56
|
+
}
|
57
|
+
|
58
|
+
if (r >= arrL.length - 1) {
|
59
|
+
if (initLimit === limit) isFloat = true;
|
60
|
+
arrL.push(48);
|
61
|
+
limit -= 1;
|
62
|
+
}
|
63
|
+
|
64
|
+
r += 1;
|
65
|
+
digit = 48;
|
66
|
+
|
67
|
+
continue;
|
68
|
+
}
|
69
|
+
|
70
|
+
for (let i = arrR.length - 1; i >= 0; i--) {
|
71
|
+
const idx = r - (arrR.length - 1 - i);
|
72
|
+
|
73
|
+
if (arrL[idx] < arrR[i]) {
|
74
|
+
arrL[idx] = arrL[idx] - arrR[i] + 58;
|
75
|
+
arrL[idx - 1] -= 1;
|
76
|
+
} else {
|
77
|
+
arrL[idx] = arrL[idx] - arrR[i] + 48;
|
78
|
+
}
|
79
|
+
}
|
80
|
+
|
81
|
+
digit += 1;
|
82
|
+
}
|
83
|
+
|
84
|
+
const multipliedResult = [];
|
85
|
+
let count = 0;
|
86
|
+
|
87
|
+
if (result[0] === 48) {
|
88
|
+
let isGrZero = false;
|
89
|
+
|
90
|
+
for (let i = 0; i < result.length; i++) {
|
91
|
+
if (!isGrZero) result[i] > 48 ? isGrZero = true : count += 1;
|
92
|
+
|
93
|
+
isGrZero && multipliedResult.push(result[i]);
|
94
|
+
}
|
95
|
+
|
96
|
+
for (let i = 0; i < count; i++) {
|
97
|
+
multipliedResult.push(48);
|
98
|
+
intLength -= 1;
|
99
|
+
}
|
100
|
+
}
|
101
|
+
|
102
|
+
const isZero = result.length === count;
|
103
|
+
|
104
|
+
return {
|
105
|
+
array: result[0] === 48 ? multipliedResult : result,
|
106
|
+
isFloat: isZero ? false : isFloat,
|
107
|
+
isNegative: isZero ? false : isNegative,
|
108
|
+
intLength: isZero ? 1 : intLength,
|
109
|
+
};
|
110
|
+
};
|
package/src/mul/index.ts
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
import { a2sMD, s2aMD } from "../shared/utils.ts";
|
2
|
+
import { multiplication } from "./utils.ts";
|
3
|
+
|
4
|
+
/** This function multiplies 2 numbers (as string). */
|
5
|
+
export const mul = (strs: string[]): string => {
|
6
|
+
const arrays = strs.map((str) => s2aMD(str));
|
7
|
+
const inputData = arrays.reduce((left, right) => {
|
8
|
+
if (left.array.length === 0) return right;
|
9
|
+
|
10
|
+
return multiplication(
|
11
|
+
[left.array, left.intLength],
|
12
|
+
[right.array, right.intLength],
|
13
|
+
left.isNegative !== right.isNegative,
|
14
|
+
);
|
15
|
+
}, { array: [], intLength: 0, isNegative: false, isFloat: false });
|
16
|
+
|
17
|
+
return a2sMD(
|
18
|
+
inputData.array,
|
19
|
+
inputData.intLength != inputData.array.length,
|
20
|
+
inputData.isNegative,
|
21
|
+
inputData.intLength,
|
22
|
+
);
|
23
|
+
};
|
package/src/mul/types.ts
ADDED
package/src/mul/utils.ts
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
import type { Multiplication } from "./types.ts";
|
2
|
+
|
3
|
+
/** This function multiplies 2 numbers (as array). */
|
4
|
+
export const multiplication: Multiplication = (
|
5
|
+
[arrL, intL],
|
6
|
+
[arrR, intR],
|
7
|
+
isNegative,
|
8
|
+
) => {
|
9
|
+
if (
|
10
|
+
arrL.length === 0 || arrR.length === 0 ||
|
11
|
+
(arrL.length === 1 && arrL[0] === 48) ||
|
12
|
+
(arrR.length === 1 && arrR[0] === 48)
|
13
|
+
) {
|
14
|
+
return { array: [48], intLength: 1, isFloat: false, isNegative: false };
|
15
|
+
}
|
16
|
+
|
17
|
+
const dec = (arrL.length - intL) + (arrR.length - intR);
|
18
|
+
|
19
|
+
const [left, right] = arrL.length >= arrR.length
|
20
|
+
? [arrL, arrR]
|
21
|
+
: [arrR, arrL];
|
22
|
+
|
23
|
+
const sums: number[] = Array(right.length + left.length - 1);
|
24
|
+
|
25
|
+
for (let i = right.length - 1; i >= 0; i--) {
|
26
|
+
for (let j = left.length - 1; j >= 0; j--) {
|
27
|
+
const idx = j + i;
|
28
|
+
|
29
|
+
sums[idx] = (sums[idx] ?? 0) +
|
30
|
+
(left[j] - 48) * (right[i] - 48);
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
34
|
+
const result = Array(sums.length);
|
35
|
+
let idx = sums.length - 1;
|
36
|
+
let carryOver = 0;
|
37
|
+
let currNum = 0;
|
38
|
+
let nextNum = 0;
|
39
|
+
|
40
|
+
while (idx >= 0) {
|
41
|
+
currNum = sums[idx] ?? 0;
|
42
|
+
nextNum = (currNum + carryOver) % 10;
|
43
|
+
carryOver = (carryOver + currNum) / 10 | 0;
|
44
|
+
result[idx] = nextNum + 48;
|
45
|
+
idx -= 1;
|
46
|
+
}
|
47
|
+
|
48
|
+
carryOver > 0 && result.unshift(carryOver + 48);
|
49
|
+
|
50
|
+
return {
|
51
|
+
array: result,
|
52
|
+
intLength: result.length - dec,
|
53
|
+
isFloat: dec > 0,
|
54
|
+
isNegative,
|
55
|
+
};
|
56
|
+
};
|