@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.
Files changed (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +129 -0
  3. package/build.ts +45 -0
  4. package/index.ts +6 -0
  5. package/npm/LICENSE +21 -0
  6. package/npm/README.md +129 -0
  7. package/npm/index.d.ts +5 -0
  8. package/npm/index.js +5 -0
  9. package/npm/package-lock.json +16 -0
  10. package/npm/package.json +57 -0
  11. package/npm/src/add/index.d.ts +2 -0
  12. package/npm/src/add/index.js +19 -0
  13. package/npm/src/add/types.d.ts +2 -0
  14. package/npm/src/add/utils.d.ts +3 -0
  15. package/npm/src/add/utils.js +48 -0
  16. package/npm/src/div/index.d.ts +2 -0
  17. package/npm/src/div/index.js +15 -0
  18. package/npm/src/div/types.d.ts +2 -0
  19. package/npm/src/div/utils.d.ts +2 -0
  20. package/npm/src/div/utils.js +90 -0
  21. package/npm/src/mul/index.d.ts +2 -0
  22. package/npm/src/mul/index.js +12 -0
  23. package/npm/src/mul/types.d.ts +2 -0
  24. package/npm/src/mul/utils.d.ts +3 -0
  25. package/npm/src/mul/utils.js +42 -0
  26. package/npm/src/shared/types.d.ts +4 -0
  27. package/npm/src/shared/utils.d.ts +5 -0
  28. package/npm/src/shared/utils.js +108 -0
  29. package/npm/src/sub/index.d.ts +2 -0
  30. package/npm/src/sub/index.js +19 -0
  31. package/npm/src/sub/types.d.ts +2 -0
  32. package/npm/src/sub/utils.d.ts +3 -0
  33. package/npm/src/sub/utils.js +76 -0
  34. package/npm/src/types.d.ts +6 -0
  35. package/package.json +57 -0
  36. package/src/add/index.ts +34 -0
  37. package/src/add/types.ts +7 -0
  38. package/src/add/utils.ts +54 -0
  39. package/src/div/index.ts +26 -0
  40. package/src/div/types.ts +8 -0
  41. package/src/div/utils.ts +110 -0
  42. package/src/mul/index.ts +23 -0
  43. package/src/mul/types.ts +7 -0
  44. package/src/mul/utils.ts +56 -0
  45. package/src/shared/types.ts +16 -0
  46. package/src/shared/utils.ts +130 -0
  47. package/src/sub/index.ts +35 -0
  48. package/src/sub/types.ts +6 -0
  49. package/src/sub/utils.ts +86 -0
  50. package/src/types.ts +6 -0
  51. package/tsconfig.json +9 -0
@@ -0,0 +1,3 @@
1
+ import type { Multiplication } from "./types.d.ts";
2
+ /** This function multiplies 2 numbers (as array). */
3
+ export declare const multiplication: Multiplication;
@@ -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,4 @@
1
+ import type { InputData } from "../types.d.ts";
2
+ export type A2S = (array: number[], isFloat: boolean, isNegative?: boolean, intLength?: number) => string;
3
+ export type S2ASA = (string: string) => InputData;
4
+ export type S2AMD = (strings: string) => InputData;
@@ -0,0 +1,5 @@
1
+ import type { A2S, S2AMD, S2ASA } from "./types.d.ts";
2
+ export declare const a2sMD: A2S;
3
+ export declare const a2sSA: A2S;
4
+ export declare const s2aSA: S2ASA;
5
+ export declare const s2aMD: S2AMD;
@@ -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,2 @@
1
+ /** This function subtracts 2 numbers (as string). */
2
+ export declare function sub(strs: string[]): string;
@@ -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,2 @@
1
+ import type { InputData } from "../types.d.ts";
2
+ export type Subtract = (L: [number[], number], R: [number[], number]) => InputData;
@@ -0,0 +1,3 @@
1
+ import type { Subtract } from "./types.d.ts";
2
+ /** This function subtracts 2 numbers (as array). */
3
+ export declare const subtract: Subtract;
@@ -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
+ };
@@ -0,0 +1,6 @@
1
+ export type InputData = {
2
+ array: number[];
3
+ intLength: number;
4
+ isNegative: boolean;
5
+ isFloat: boolean;
6
+ };
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
+ }
@@ -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
+ }
@@ -0,0 +1,7 @@
1
+ import type { InputData } from "../types.ts";
2
+
3
+ export type Addition = (
4
+ L: [number[], number],
5
+ R: [number[], number],
6
+ isNegative: boolean
7
+ ) => InputData;
@@ -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
+ };
@@ -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
+ };
@@ -0,0 +1,8 @@
1
+ import type { InputData } from "../types.ts";
2
+
3
+ export type Division = (
4
+ L: [number[], number],
5
+ R: [number[], number],
6
+ isNegative: boolean,
7
+ initLimit: number
8
+ ) => InputData;
@@ -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
+ };
@@ -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
+ };
@@ -0,0 +1,7 @@
1
+ import type { InputData } from "../types.ts";
2
+
3
+ export type Multiplication = (
4
+ arrL: [number[], number],
5
+ arrR: [number[], number],
6
+ isNegative: boolean
7
+ ) => InputData;
@@ -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
+ };