由于平时在做题时会用到数字字符串模拟大数加减乘除,但是网上的大部分代码都只是针对大整数而言,无法对小数和负数进行运算。所以特地写了一个类,包括了大数相加 、大数相减、大数相乘、大整数相除。
大数相加 (可以是整数、小数、负数)
大数相减 (可以是整数、小数、负数)
大数相乘 (可以是整数、小数、负数)
大整数相除 (只能是正整数,返回商和余数)
这些方法都是模拟手算过程实现,在本地测试都没什么问题,如果大家在使用过程中发现问题,希望能反馈一下,让我进一步完善。
//大数四则运算
//大数加法(正负整数,正负小数都行)
//大数减法(正负整数,正负小数都行)
//大数乘法(正负整数,正负小数都行)
//大整数除法(只能正整数相除,给出商和余数)
//有两个用字符串表示的非常大的大整数, 算出他们的四则运算,也是用字符串表示。不能用系统自带的大整数类型。
#include
#include
using namespace std;
struct Division_result {
string quotient;
string remainder;
};
class Four_Arithmetic_Operations {
public:
string Sum_of_String(string s1, string s2) {
if (Is_InValid_Strings("Sum_of_String", s1, s2)) return "";
bool S1Sign = true, S2Sign = true; if (s1[0] == '-') S1Sign = false, s1.erase(s1.begin()); if (s2[0] == '-') S2Sign = false, s2.erase(s2.begin());//判断是否有负号
if (!S1Sign && S2Sign) return Substration_of_String(s2, s1);
else if (S1Sign && !S2Sign) return Substration_of_String(s1, s2);
else if (!S1Sign && !S2Sign) return "-" + Sum_of_String(s1, s2);
else {
int s1TailLength = 0, s2TailLength = 0;
for (int i = 0; i < s1.size(); i++) if (s1[i] == '.') { s1TailLength = (int)s1.size() - 1 - i; s1.erase(s1.begin() + i); break; }//去除s1小数点,记录小数位数
for (int i = 0; i < s2.size(); i++) if (s2[i] == '.') { s2TailLength = (int)s2.size() - 1 - i; s2.erase(s2.begin() + i); break; }//去除s2小数点,记录小数位数
int TailLength = (s1TailLength > s2TailLength) ? s1TailLength : s2TailLength;
if (TailLength != s1TailLength) s1 += string(TailLength - s1TailLength, '0');//小数部分对齐补0
if (TailLength != s2TailLength) s2 += string(TailLength - s2TailLength, '0');//小数部分对齐补0
int Total_Length = s1.size() > s2.size() ? (int)s1.size() : (int)s2.size();
if (Total_Length != s1.size()) s1 = string(Total_Length - s1.size(), '0') + s1;//整数部分对齐补0
if (Total_Length != s2.size()) s2 = string(Total_Length - s2.size(), '0') + s2;//整数部分对齐补0
reverse(s1.begin(), s1.end());
reverse(s2.begin(), s2.end());
string result(Total_Length + 1, '0');
for (int i = 0; i < Total_Length; i++)
{
int k = s1[i] + s2[i] + result[i] - 3 * '0';
string h = to_string(k % 10); result[i] = h[0];
h = to_string(k / 10); result[i + 1] = h[0];
}
reverse(result.begin(), result.end());
if (TailLength != 0) {
result.insert(result.size() - TailLength, ".");//如果有小数部分插入小数点
while (result.back() == '0') result.erase(result.end() - 1);//去除小数部分末尾的0
if (result.back() == '.') result.erase(result.end() - 1);
}
if (result[0] == '0') result.erase(result.begin());
return result;
}
}
string Substration_of_String(string s1, string s2) {
if (Is_InValid_Strings("Substration_of_String", s1, s2)) return "";
bool S1Sign = true, S2Sign = true; if (s1[0] == '-') S1Sign = false, s1.erase(s1.begin()); if (s2[0] == '-') S2Sign = false, s2.erase(s2.begin());//判断是否有负号
if (!S1Sign && S2Sign) return "-" + Sum_of_String(s1, s2);
else if (S1Sign && !S2Sign) return Sum_of_String(s1, s2);
else if (!S1Sign && !S2Sign) return Substration_of_String(s2, s1);
else {
int s1TailLength = 0, s2TailLength = 0;
for (int i = 0; i < s1.size(); i++) if (s1[i] == '.') { s1TailLength = (int)s1.size() - 1 - i; s1.erase(s1.begin() + i); break; }//去除s1小数点,记录小数位数
for (int i = 0; i < s2.size(); i++) if (s2[i] == '.') { s2TailLength = (int)s2.size() - 1 - i; s2.erase(s2.begin() + i); break; }//去除s2小数点,记录小数位数
int TailLength = (s1TailLength > s2TailLength) ? s1TailLength : s2TailLength;
if (TailLength != s1TailLength) s1 += string(TailLength - s1TailLength, '0');//小数部分对齐补0
if (TailLength != s2TailLength) s2 += string(TailLength - s2TailLength, '0');//小数部分对齐补0
int Total_Length = s1.size() > s2.size() ? (int)s1.size() : (int)s2.size();
if (Total_Length != s1.size()) s1 = string(Total_Length - s1.size(), '0') + s1;//整数部分对齐补0
if (Total_Length != s2.size()) s2 = string(Total_Length - s2.size(), '0') + s2;//整数部分对齐补0
bool Sign = true;//正负符号标记
if (!(Is_S1_BiggerThan_S2(s1, s2) || s1 == s2)) {
s1.swap(s2);//将s1作为大的数存放,s2作为小的数
Sign = false;
}
reverse(s1.begin(), s1.end());
reverse(s2.begin(), s2.end());
int length = s1.size() > s2.size() ? (int)s1.size() : (int)s2.size();//记录谁最长
if (length == s1.size()) s2 += string(length - s2.size(), '0');//对齐补0
if (length == s2.size()) s1 += string(length - s1.size(), '0');//对齐补0
int borrow = 0; string result(length, '0');//存放结果
for (int i = 0; i < length; i++) {
if (s1[i] >= s2[i] + borrow) { result[i] = '0' + s1[i] - s2[i] - borrow; borrow = 0; }
else { result[i] = '0' + 10 + s1[i] - s2[i] - borrow; borrow = 1; }
}
reverse(result.begin(), result.end());
while (result.size() > 1 && result[0] == '0') result.erase(result.begin());
if (TailLength != 0) {
result.insert(result.size() - TailLength, ".");//如果有小数部分插入小数点
while (result.back() == '0') result.erase(result.end() - 1);//去除小数部分末尾的0
if (result.back() == '.') result.erase(result.end() - 1);
}
if (!Sign) result = "-" + result;
return result;
}
}
string Multiply_of_String(string s1, string s2) {
if (Is_InValid_Strings("Multiply_of_String", s1, s2)) return "";
int s1TailLength = 0, s2TailLength = 0; int TailLength = 0;
bool S1Sign = true, S2Sign = true; if (s1[0] == '-') S1Sign = false, s1.erase(s1.begin()); if (s2[0] == '-') S2Sign = false, s2.erase(s2.begin());//判断是否有负号
for (int i = 0; i < s1.size(); i++) if (s1[i] == '.') { s1TailLength = (int)s1.size() - 1 - i; s1.erase(s1.begin() + i); break; }//去除是s1小数点,记录小数位数
for (int i = 0; i < s2.size(); i++) if (s2[i] == '.') { s2TailLength = (int)s2.size() - 1 - i; s2.erase(s2.begin() + i); break; }//去除s2小数点,记录小数位数
TailLength = s1TailLength + s2TailLength;
string C(s1.size() + s2.size(), '0'); int carry_num;//进位数
for (int i = (int)s2.size() - 1; i >= 0; --i) {
carry_num = 0;
for (int j = (int)s1.size() - 1; j >= 0; --j) {
int T = (s2[i] - '0')*(s1[j] - '0');
T += (C[j + i + 1] - '0') + carry_num;
carry_num = T / 10; C[j + i + 1] = '0' + T % 10;
}
if (carry_num != 0) C[i] = '0' + carry_num;
}
if (TailLength != 0) {
C.insert(C.size() - TailLength, ".");//如果有小数部分插入小数点
while (C.back() == '0') C.erase(C.end() - 1);//去除小数部分末尾的0
}
if (C.back() == '.') C.erase(C.end() - 1);
while (!C.empty() && C.front() == '0') C.erase(C.begin());
if (C.empty()) C += '0';
else if (S1Sign^S2Sign) C = "-" + C;//两者符号相异为需添加负号
return C;
}
Division_result Division_of_string(string dividend, string divisor) {
if (Is_InValid_Division_Strings("Division_of_string", dividend, divisor)) return Division_result();
string remainder = ""; string quotient;
for (int i = 0; dividend[i]; i++)
{
remainder += dividend[i];
if (Is_S1_BiggerThan_S2(remainder, divisor) || remainder == divisor) {
for (string factor = "9"; factor >= "1"; factor[0]--) {
string Diviior_Fac = Multiply_of_String(divisor, factor);
if (Is_S1_BiggerThan_S2(remainder, Diviior_Fac) || remainder == Diviior_Fac) {
quotient += factor;
remainder = Substration_of_String(remainder, Diviior_Fac);
break;
}
}
}
}
while (remainder.size() > 1 && remainder[0] == '0')remainder.erase(remainder.begin());
if (quotient.empty()) quotient = '0';
return Division_result() = { quotient, remainder };
}
private:
bool Is_S1_BiggerThan_S2(string s1, string s2) {
if (s1.size() < s2.size()) return false;
else if (s1.size() > s2.size()) return true;
else {
for (int i = 0; i < s1.size(); i++) {
if (s1[i] > s2[i]) return true;
else if (s1[i] < s2[i]) return false;
}
}
return false;
}
bool Is_Valid_StringNum(string Str) {
int state = 1; int i = 0;
while (i < Str.size()) {
switch (state)
{
case 1:
if (Str[i] == '-' || '0' <= Str[i] && Str[i] <= '9') state = 2;
else return false;
break;
case 2:
if (Str[i] == '.') state = 3;
else if (Str[i]<'0' || Str[i] > '9') return false;
break;
case 3:
if (Str[i]<'0' || Str[i] > '9') return false;
break;
default:
break;
}
i++;
}
return true;
}
bool Is_InValid_Strings(string fun_name, string s1, string s2)
{
if (!Is_Valid_StringNum(s1) || !Is_Valid_StringNum(s2)) {
cout << fun_name << "(" << s1 << "," << s2 << ")中";
if (!Is_Valid_StringNum(s1)) cout << ",s1输入了无效数字字符串";
if (!Is_Valid_StringNum(s2)) cout << ",s2输入了无效数字字符串";
cout << endl;
return true;
}
return false;
}
bool Is_InValid_Division_Strings(string fun_name, string s1, string s2)
{
bool valids1 = true, valids2 = true;
for (int i = 0; i < s1.size(); i++) if (s1[i]<'0' || s1[i]>'9') valids1 = false;
for (int i = 0; i < s2.size(); i++) if (s2[i]<'0' || s2[i]>'9') valids2 = false;
if (!valids1 || !valids2) {
cout << fun_name << "(" << s1 << "," << s2 << ")中";
if (!valids1) cout << ",s1输入了无效数字字符串";
if (!valids2) cout << ",s2输入了无效数字字符串";
cout << endl;
return true;
}
return false;
}
};
int main()
{
string s1 = "1219326320073159566072245112635269"; string s2 = "98765432123456789"; string quotient_True_ans = "12345678987654321"; string remainder_True_ans = "0";//两大整数相除,输出12345678987654321
//string s1 = "122"; string s2 = "11"; string quotient_True_ans = "11"; string remainder_True_ans = "1";//两大整数相除
//string s1 = "11"; string s2 = "121"; string quotient_True_ans = "0"; string remainder_True_ans = "11";//两大整数相除
Four_Arithmetic_Operations ari;
Division_result result=ari.Division_of_string(s1, s2);
cout << s1 << "/" << s2 << "=商:" << result.quotient << " 余数:" << result.remainder << endl;
cout << "输出:" << ((result.quotient == quotient_True_ans && result.remainder == remainder_True_ans) ? "正确" : "错误") << endl;
cout << ari.Substration_of_String("-25.500", "-00.1562") << endl;
cout << ari.Sum_of_String("-25", "00.15620") << endl;
cout << ari.Multiply_of_String("-25.500", "-00.1562") << endl;
cout << ari.Multiply_of_String("25.5", "-0") << endl;
return 0;
}