Skip to content

Commit

Permalink
feature: big number add and minus
Browse files Browse the repository at this point in the history
  • Loading branch information
wangmengCC committed Aug 31, 2023
1 parent 70ec782 commit e87d6d1
Show file tree
Hide file tree
Showing 2 changed files with 246 additions and 0 deletions.
49 changes: 49 additions & 0 deletions 04-algrithm/08-bigNumber/__tests__/index.spec.js
Original file line number Diff line number Diff line change
@@ -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");
});
});
});
197 changes: 197 additions & 0 deletions 04-algrithm/08-bigNumber/index.js
Original file line number Diff line number Diff line change
@@ -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,
};

0 comments on commit e87d6d1

Please sign in to comment.