From e87d6d1d1dcdf953d44d999a1ef837a039f4fa9f Mon Sep 17 00:00:00 2001 From: wangmeng Date: Thu, 31 Aug 2023 16:48:38 +0800 Subject: [PATCH 1/3] feature: big number add and minus --- .../08-bigNumber/__tests__/index.spec.js | 49 +++++ 04-algrithm/08-bigNumber/index.js | 197 ++++++++++++++++++ 2 files changed, 246 insertions(+) create mode 100644 04-algrithm/08-bigNumber/__tests__/index.spec.js create mode 100644 04-algrithm/08-bigNumber/index.js diff --git a/04-algrithm/08-bigNumber/__tests__/index.spec.js b/04-algrithm/08-bigNumber/__tests__/index.spec.js new file mode 100644 index 0000000..2b18adc --- /dev/null +++ b/04-algrithm/08-bigNumber/__tests__/index.spec.js @@ -0,0 +1,49 @@ +const { bigAdd, bigMin } = require("../20230826大数加减"); + +describe("大数加减", () => { + describe("加法", () => { + it("普通加法", () => { + expect(bigAdd("1", "1")).toEqual("2"); + expect(bigAdd("9", "1")).toEqual("10"); + expect(bigAdd("10", "1")).toEqual("11"); + expect(bigAdd("19999", "1")).toEqual("20000"); + expect(bigAdd("99999", "1")).toEqual("100000"); + expect(bigAdd("100", "1")).toEqual("101"); + expect(bigAdd("1", "199")).toEqual("200"); + }); + }); + describe("减法", () => { + it("正减正", () => { + expect(bigMin("1", "1")).toEqual("0"); + expect(bigMin("0", "1")).toEqual("-1"); + expect(bigMin("10", "1")).toEqual("9"); + expect(bigMin("19", "1")).toEqual("18"); + expect(bigMin("100", "1")).toEqual("99"); + expect(bigMin("1", "100")).toEqual("-99"); + }); + it("正减负", () => { + expect(bigMin("1", "-1")).toEqual("2"); + expect(bigMin("0", "-1")).toEqual("1"); + expect(bigMin("10", "-1")).toEqual("11"); + expect(bigMin("19", "-1")).toEqual("20"); + expect(bigMin("100", "-1")).toEqual("101"); + expect(bigMin("1", "-100")).toEqual("101"); + }); + it("负减正", () => { + expect(bigMin("-1", "1")).toEqual("-2"); + expect(bigMin("-2", "1")).toEqual("-3"); + expect(bigMin("-10", "1")).toEqual("-11"); + expect(bigMin("-19", "1")).toEqual("-20"); + expect(bigMin("-100", "1")).toEqual("-101"); + expect(bigMin("-1", "100")).toEqual("-101"); + }); + it("负减负", () => { + expect(bigMin("-1", "-1")).toEqual("0"); + expect(bigMin("-2", "-1")).toEqual("-1"); + expect(bigMin("-10", "-1")).toEqual("-9"); + expect(bigMin("-19", "-1")).toEqual("-18"); + expect(bigMin("-100", "-1")).toEqual("-99"); + expect(bigMin("-1", "-100")).toEqual("99"); + }); + }); +}); diff --git a/04-algrithm/08-bigNumber/index.js b/04-algrithm/08-bigNumber/index.js new file mode 100644 index 0000000..9e9f8ff --- /dev/null +++ b/04-algrithm/08-bigNumber/index.js @@ -0,0 +1,197 @@ +function minus(a1, a2) { + let carry = 0; + let i = a1.length - 1; + let j = a2.length - 1; + let arr = []; + while (a1[i]) { + let x = Number(a1[i]); + let y = 0; + if (a2[j]) { + y = Number(a2[j]); + } + let temp; + if (x - y + carry < 0) { + temp = x + 10; + } else { + temp = x; + } + let res = temp - y + carry; + if (x - y + carry < 0) { + carry = -1; + } else { + carry = 0; + } + arr.unshift(res); + i--; + j--; + } + while (arr[0] === 0 && arr.length > 1) { + arr.shift(); + } + return arr.join(""); +} + +/** + * + * @param {string} a1 + * @param {string} a2 + * @returns {number} + */ +// 正负数,比较大数大小 +function compare(a1, a2) { + if (a1.startsWith("-") && !a2.startsWith("-")) { + return -1; + } else if (!a1.startsWith("-") && a2.startsWith("-")) { + return 1; + } else if (a1.startsWith("-") && a2.startsWith("-")) { + return compareNegative(a1, a2); + } else if (!a1.startsWith("-") && !a2.startsWith("-")) { + return comparePositive(a1, a2); + } + return 0; +} + +function compareNegative(a1, a2) { + // 谁位数多谁小 + if (a1.length > a2.length) { + return -1; + } else if (a1.length < a2.length) { + return 1; + } else { + let i = 0; + while (a1[i] && a2[i]) { + /// 123 789 + if (a1[i] > a2[i]) { + return -1; + } else if (a1[i] < a2[i]) { + return 1; + } else { + i++; + } + } + } + return 0; +} + +function comparePositive(a1, a2) { + if (a1.length > a2.length) { + return 1; + } else if (a1.length < a2.length) { + return -1; + } else { + let i = 0; + while (a1[i] && a2[i]) { + if (a1[i] > a2[i]) { + return 1; + } else if (a1[i] < a2[i]) { + return -1; + } else { + i++; + } + } + } + return 0; +} + +/** + * 大数加法 + * @param {number} a1 加数 1 + * @param {number} a2 加数 2 + * @returns {number} 加法结果 + */ +function bigAdd(a1, a2) { + let carry = 0; + let i = a1.length - 1; + let j = a2.length - 1; + let arr = []; + while (a1[i] || a2[j]) { + let x = 0; + if (a1[i]) { + x = Number(a1[i]); + } + let y = 0; + if (a2[j]) { + y = Number(a2[j]); + } + let res = (x + y + carry) % 10; + arr.unshift(res); + carry = Math.floor((x + y + carry) / 10); + i--; + j--; + } + if (carry) { + arr.unshift(carry); + } + return arr.join(""); +} + +/** + * 大数减法,包含正负数 + * @param {number} a1 被减数 + * @param {number} a2 减数 + * @returns {number} 减法结果 + */ +function bigMin(a1, a2) { + // 负数减负数(去掉符号,大减小)(如果 a2 > a1,正号;如果 a1 > a2,负号) + // 正数减负数(去掉符号,加起来)(正号) + // 正数减正数(去掉符号,大减小)(如果 a2 > a1,负号;如果 a1 > a2,正号) + // 负数减正数(去掉符号,加起来)(负号) + let s = ""; + + if ( + // 小减大,负数 + (a1[0] === "-" && a2[0] === "-") || + // 小减大,负数 + (!a1[0] === "-" && !a2[0] === "-") + ) { + if (compare(a1, a2) < 0) { + // -123 - -12 + s = "-"; + } + } else if (a1[0] === "-" && a2[0] !== "-") { + // -123 - 789 + s = "-"; + } + + let res = ""; + if ( + // 正 - 负 + (a1[0] !== "-" && a2[0] === "-") || + // 负 - 正 + (a1[0] === "-" && a2[0] !== "-") + ) { + if (a1[0].startsWith("-")) { + a1 = a1.slice(1); + } + if (a2[0].startsWith("-")) { + a2 = a2.slice(1); + } + res = bigAdd(a1, a2); + } else if ( + // 正 - 正 + (a1[0] !== "-" && a2[0] !== "-") || + // 负 - 负 + (a1[0] === "-" && a2[0] === "-") + ) { + if (a1[0].startsWith("-")) { + a1 = a1.slice(1); + } + if (a2[0].startsWith("-")) { + a2 = a2.slice(1); + } + if (compare(a1, a2) > 0) { + res = minus(a1, a2); + } else { + a1 = a2; + a2 = a1; + res = minus(a1, a2); + } + } + + return `${s}${res}`; +} + +module.exports = { + bigAdd, + bigMin, +}; From 549aae38ce385202c6ddd9ed8c1731c01463d9ff Mon Sep 17 00:00:00 2001 From: wangmeng Date: Thu, 31 Aug 2023 16:58:11 +0800 Subject: [PATCH 2/3] feat: some fix --- 04-algrithm/08-bigNumber/__tests__/index.spec.js | 2 +- 04-algrithm/08-bigNumber/index.js | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/04-algrithm/08-bigNumber/__tests__/index.spec.js b/04-algrithm/08-bigNumber/__tests__/index.spec.js index 2b18adc..47a7017 100644 --- a/04-algrithm/08-bigNumber/__tests__/index.spec.js +++ b/04-algrithm/08-bigNumber/__tests__/index.spec.js @@ -1,4 +1,4 @@ -const { bigAdd, bigMin } = require("../20230826大数加减"); +const { bigAdd, bigMin } = require("../index"); describe("大数加减", () => { describe("加法", () => { diff --git a/04-algrithm/08-bigNumber/index.js b/04-algrithm/08-bigNumber/index.js index 9e9f8ff..cee3c56 100644 --- a/04-algrithm/08-bigNumber/index.js +++ b/04-algrithm/08-bigNumber/index.js @@ -142,7 +142,7 @@ function bigMin(a1, a2) { // 小减大,负数 (a1[0] === "-" && a2[0] === "-") || // 小减大,负数 - (!a1[0] === "-" && !a2[0] === "-") + (a1[0] !== "-" && a2[0] !== "-") ) { if (compare(a1, a2) < 0) { // -123 - -12 @@ -182,8 +182,9 @@ function bigMin(a1, a2) { if (compare(a1, a2) > 0) { res = minus(a1, a2); } else { + let tmp = a1; a1 = a2; - a2 = a1; + a2 = tmp; res = minus(a1, a2); } } From f3d8062b6ab7b3d73c2af3ba90238fd83c9e7736 Mon Sep 17 00:00:00 2001 From: wangmeng Date: Thu, 31 Aug 2023 17:00:56 +0800 Subject: [PATCH 3/3] chore: add article link --- 04-algrithm/08-bigNumber/index.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/04-algrithm/08-bigNumber/index.js b/04-algrithm/08-bigNumber/index.js index cee3c56..4d6768a 100644 --- a/04-algrithm/08-bigNumber/index.js +++ b/04-algrithm/08-bigNumber/index.js @@ -1,3 +1,7 @@ +/** + * 相关文章地址:https://juejin.cn/post/7273141970057543717 + */ + function minus(a1, a2) { let carry = 0; let i = a1.length - 1;