@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
|
+
};
|