高精度 加、减、乘、除结构体解答
2024-11-20 20:04:13
发布于:北京
1阅读
0回复
0点赞
汇总
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
// 函数功能:去除字符串表示的数字中的前导0
// 参数说明:num是传入的字符串引用,代表要处理的数字字符串
// 例如:输入 "00123",处理后变为 "123"
void removeLeadingZeros(string& num) {
// 当字符串长度大于1且末尾字符是'0'时,不断删除末尾的'0'
while (num.size() > 1 && num.back() == '0') {
num.pop_back();
}
}
// 函数功能:比较两个字符串表示的数字大小
// 参数说明:a和b是要比较的两个数字字符串
// 返回值:如果a的长度不等于b的长度,返回a的长度是否大于b的长度;
// 如果长度相等,返回a是否大于等于b
// 例如:"123"和"45"比较,返回true;"123"和"123"比较,返回true;"12"和"123"比较,返回false
bool compare(const string& a, const string& b) {
if (a.size()!= b.size()) {
return a.size() > b.size();
}
return a >= b;
}
// 定义一个名为BigInt的类,用于表示高精度整数
class BigInt {
public:
string num;
// 默认构造函数,用于创建一个空的BigInt对象
BigInt() {}
// 构造函数,用于根据传入的字符串创建BigInt对象,并去除前导0
// 参数说明:s是传入的字符串,代表要初始化的数字
BigInt(const string& s) : num(s) {
removeLeadingZeros(num);
}
// 重载加法运算符,实现两个BigInt对象的加法运算
// 参数说明:other是要与当前对象相加的另一个BigInt对象
// 返回值:相加结果的BigInt对象
BigInt operator+(const BigInt& other) const {
string result;
// 分别指向当前对象和另一个对象数字字符串的末尾位置
int i = num.size() - 1;
int j = other.num.size() - 1;
int carry = 0; // 进位标志,初始化为0
// 只要两个数字字符串还有未处理的位,或者还有进位,就继续循环
while (i >= 0 || j >= 0 || carry) {
int sum = carry;
if (i >= 0) {
// 将当前对象当前位的数字转换为整数并加到总和中
sum += num[i] - '0';
i--;
}
if (j >= 0) {
// 将另一个对象当前位的数字转换为整数并加到总和中
sum += other.num[j] - '0';
j--;
}
carry = sum / 10; // 计算新的进位
result.push_back((sum % 10) + '0'); // 将当前位的结果添加到结果字符串中
}
reverse(result.begin(), result.end()); // 反转结果字符串,得到正确的顺序
removeLeadingZeros(result); // 去除结果中的前导0
return BigInt(result); // 返回相加结果的BigInt对象
}
// 重载减法运算符,实现两个BigInt对象的减法运算
// 参数说明:other是要与当前对象相减的另一个BigInt对象
// 返回值:相减结果的BigInt对象,如果被减数小于减数则抛出异常
BigInt operator-(const BigInt& other) const {
// 如果当前对象表示的数字小于另一个对象表示的数字,抛出异常
if (!compare(num, other.num)) {
throw runtime_error("Negative result in subtraction");
}
string result;
int i = num.size() - 1;
int j = other.num.size() - 1;
int borrow = 0; // 借位标志,初始化为0
// 只要两个数字字符串还有未处理的位,就继续循环
while (i >= 0 || j >= 0) {
int diff = borrow;
if (i >= 0) {
// 将当前对象当前位的数字转换为整数并加到差值中
diff += num[i] - '0';
i--;
}
if (j >= 0) {
// 将另一个对象当前位的数字转换为整数并从差值中减去
diff -= other.num[j] - '0';
j--;
}
if (diff < 0) {
// 如果差值小于0,需要借位
diff += 10;
borrow = -1;
} else {
borrow = 0;
}
result.push_back(diff + '0'); // 将当前位的结果添加到结果字符串中
}
reverse(result.begin(), result.end()); // 反转结果字符串,得到正确的顺序
removeLeadingZeros(result); // 去除结果中的前导0
return BigInt(result); // 返回相减结果的BigInt对象
}
// 重载乘法运算符,实现两个BigInt对象的乘法运算
// 参数说明:other是要与当前对象相乘的另一个BigInt对象
// 返回值:相乘结果的BigInt对象
BigInt operator*(const BigInt& other) const {
// 初始化结果字符串,长度为两个乘数数字字符串长度之和,初始值都为'0'
string result(num.size() + other.num.size(), '0');
// 遍历当前对象的每一位
for (size_t i = 0; i < num.size(); ++i) {
int carry = 0; // 进位标志,初始化为0
// 遍历另一个对象的每一位
for (size_t j = 0; j < other.num.size(); ++j) {
// 计算当前位相乘的结果以及加上之前的进位和结果字符串对应位的值
int sum = (num[i] - '0') * (other.num[j] - '0') + (result[i + j] - '0') + carry;
result[i + j] = (sum % 10) + '0'; // 更新结果字符串对应位的值
carry = sum / 10; // 计算新的进位
}
if (carry > 0) {
// 如果还有进位,加到结果字符串的下一位
result[i + other.num.size()] += carry;
}
}
reverse(result.begin(), result.end()); // 反转结果字符串,得到正确的顺序
removeLeadingZeros(result); // 去除结果中的前导0
return BigInt(result); // 返回相乘结果的BigInt对象
}
// 重载除法运算符,简单实现两个BigInt对象的除法运算,只返回商,暂不考虑余数精确处理
// 参数说明:other是要与当前对象相除的另一个BigInt对象
// 返回值:相除结果的BigInt对象,如果被除数小于除数则返回0
BigInt operator/(const BigInt& other) const {
// 如果当前对象表示的数字小于另一个对象表示的数字,返回0
if (!compare(num, other.num)) {
return BigInt("0");
}
string quotient;
BigInt remainder("0");
BigInt divisor = other;
// 遍历被除数的每一位
for (size_t i = 0; i < num.size(); ++i) {
remainder.num.push_back(num[i]);
removeLeadingZeros(remainder.num);
int q = 0;
// 只要余数大于等于除数,就继续做减法并增加商的值
while (compare(remainder.num, divisor.num)) {
remainder = remainder - divisor;
q++;
}
quotient.push_back(q + '0');
}
reverse(quotient.begin(), quotient.end()); // 反转商的字符串,得到正确的顺序
removeLeadingZeros(quotient); // 去除商中的前导0
return BigInt(quotient); // 返回相除结果的BigInt对象
}
};
// 重载输出流运算符,用于输出BigInt对象
// 参数说明:os是输出流对象,bi是要输出的BigInt对象
// 返回值:输出流对象,以便支持连续输出
ostream& operator<<(ostream& os, const BigInt& bi) {
os << bi.num;
return os;
}
int main() {
BigInt a, b;
string c, d;
// 从标准输入读取两个字符串,分别代表两个要进行运算的数字
cin >> c >> d;
// 用读取到的字符串初始化两个BigInt对象
a.num = c;
b.num = d;
// 输出两个BigInt对象相加的结果
cout << a + b;
return 0;
}
这段代码实现了高精度整数的四则运算,通过定义 BigInt
类并重载相应的运算符来完成加法、减法、乘法和除法的功能,同时在 main
函数中进行了简单的输入输出测试。
这里空空如也
有帮助,赞一个