大整数运算
首先是遇到了1017 A除以B,稀里糊涂地复制了别人的答案就将其抛在脑后(偶然事件),紧接着就遇到了1022 D进制的A+B,这时突然记起学习要有打破砂锅问到底的精神,根本不是因为发现这个问题逃避不了,开始了对这个知识点的研究学习。
-
取余运算
取余就是取模,可以将其转换为对字符串中的最低数位进行取模运算。
-
整除运算
对于整除运算,需要重新写一个函数来完成字符串的除法功能。
实现字符串除法函数的做法和日常在纸上实现除法的做法是一样的,即把字符中从商到低逐位除以除数。如界某位不能整除,那么就保留它除以除数的余数,余数乘以 10 后和低一位一起进行处理。这样,就能模拟出除法的效果,但这种做法可能会前置多余的 0,这时只需取首个非0位之后的字符串,便可得到想要的结果。
#include<iostream> #include<algorithm> #include<string.h> #include<string> #include<math.h> #include<vector> using namespace std; int toBinary(unsigned int n) {//被转换十进制数在int范围内 vector<int> binary;//用vector装,跟用数组装都一样 while (n != 0) {//一直除,直到等于零 binary.push_back(n % 2);//将取模的值压进vector n /= 2;//数字也除进制数 } for (int i = binary.size() - 1; i >= 0; i--) cout << binary[i];//由于采用头插法,数字是倒着的,需逆序输出 cout << endl; } /* * 当被转换数字只能用长字符串表示时,同样地,对此字符串不断进行对2取模和对2整除运算。不同的是, * 1. 对于取模运算,可以将其转换为对字符串中的最低数位进行取模运算。 * 2. 对于整除运算,需要重新写一个函数来完成字符串的除法功能。实现字符串除法函数的做法和日常在纸上实现除法的做法是一样的,即把字符中从商到低逐位除以除数。 * 如界某位不能整除,那么就保留它除以除数的余数,余数乘以 10 后和低一位一起进行处理。这样,就能模拟出除法的效果,但这种做法可能会前置多余的 0,这时只需取首个 * 非0位之后的字符串,便可得到想要的结果。 */ string Divide(string s, int x) {//整除运算函数 int remainder = 0; for (int i = 0; i < s.size(); ++i) { int current = remainder * 10 + s[i] - '0'; s[i] = current / x + '0'; remainder = current % x; } int pos = 0; while (s[pos] == '0') pos++; return s.substr(pos); } int main() { return 0; }
上面也就看一乐,接下来是书上的代码,书上成为高精度整数,Java中有BigInteger类可以直接用,这里给出一系列模板。注意这个模板只适用于运算数和运算结果均为正整数的运算,否则会出错。
const int MAXN = 10000;//定义常量MAXN表示最大位数,即最多能表示的数字位数 struct BigInteger { int digit[MAXN];//用于存储大整数的每一位数字 int length;//表示大整数的位数 BigInteger();//⭐ BigInteger(int x);//构造函数,接受一个整数 x 并将其转换为大整数类型 BigInteger(string str);//⭐构造函数,接受一个字符串 str,并将其转换为大整数类型 BigInteger(const BigInteger& b);//构造函数,接受另外一个大整数类型的对象 b,并将其复制为新的大整数类型 BigInteger operator=(int x);//重载赋值运算符,将一个整数类型的值赋值给大整数类型对象 BigInteger operator=(string str);//重载赋值运算符,将一个字符串类型的值赋值给大整数类型对象 BigInteger operator=(const BigInteger& b);//重载赋值运算符,将另外一个大整数类型的对象赋值给当前对象 bool operator <= (const BigInteger& b);//判断当前大整数类型对象是否小于等于另外一个大整数类型对象 bool operator == (const BigInteger& b);//判断当前大整数类型对象是否等于另外一个大整数类型对象 BigInteger operator+(const BigInteger& b);//重载加法运算符,实现大整数的 + 法 BigInteger operator-(const BigInteger& b);//重载减法运算符,实现大整数的 - 法 BigInteger operator*(const BigInteger& b);//重载乘法运算符,实现大整数的 * 法 BigInteger operator/(const BigInteger& b);//重载除法运算符,实现大整数的 / 法 BigInteger operator%(const BigInteger& b);//重载取模运算符,实现大整数取模 friend istream& operator>>(istream& in, BigInteger& x);//⭐重载输入运算符,用于将用户输入的字符串或整数转换为大整数类型 friend ostream& operator<<(ostream& out, const BigInteger& x);//⭐重载输出运算符,用于输出大整数类型对象 };//该结构体的作用是用于实现大整数的基本运算,方便用户直接进行大整数的计算 istream& operator>>(istream& in, BigInteger& x) {// string str; in >> str; x = str; return in; } ostream& operator<<(ostream& out, const BigInteger& x) { for (int i = x.length - 1; i >= 0; --i) out << x.digit[i]; return out; } BigInteger::BigInteger() { memset(digit, 0, sizeof(digit)); length = 0; } BigInteger::BigInteger(int x) { memset(digit, 0, sizeof(digit)); length = 0; if (x == 0) digit[length++] = x; while (x != 0) { digit[length++] = x % 10; x /= 10; } } BigInteger::BigInteger(string str){ memset(digit, 0, sizeof(digit)); length = str.size(); for (int i = 0; i < length; ++i) digit[i] = str[length - i - 1] - '0'; } BigInteger::BigInteger(const BigInteger& b){ memset(digit, 0, sizeof(digit)); length = b.length; for (int i = 0; i < length; ++i) digit[i] = b.digit[i]; } BigInteger BigInteger::operator=(int x) { memset(digit, 0, sizeof(digit)); length = 0; if (x == 0) digit[length++] = x; while (x) { digit[length++] = x % 10; x /= 10; } return *this; } BigInteger BigInteger::operator=(string str){ memset(digit, 0, sizeof(digit)); length = str.size(); for (int i = 0; i < length; ++i) digit[i] = str[length - i - 1] - '0'; return *this; } BigInteger BigInteger::operator=(const BigInteger& b){ memset(digit, 0, sizeof(digit)); length = b.length; for (int i = 0; i < length; ++i) digit[i] = b.digit[i]; return *this; } bool BigInteger::operator<=(const BigInteger& b){ if (length < b.length) return true; else if (length > b.length) return false; else for (int i = length - 1; i >= 0; --i) { if (digit[i] == b.digit[i]) continue; else return digit[i] < b.digit[i]; } return true; } bool BigInteger::operator==(const BigInteger& b){ if (length != b.length) return false; else for (int i = length - 1; i >= 0; --i) if (digit[i] != b.digit[i]) return false; return true; } BigInteger BigInteger::operator+(const BigInteger& b){ BigInteger answer; int carry = 0; for (int i = 0; i < length || i < b.length; ++i) { int current = carry + digit[i] + b.digit[i]; carry = current / 10; answer.digit[answer.length++] = current % 10; } if (carry != 0) answer.digit[answer.length++] = carry; return answer; } BigInteger BigInteger::operator-(const BigInteger& b){ BigInteger answer; int carry = 0; for (int i = 0; i < length; ++i) { int current = digit[i] - b.digit[i] - carry; if (current < 0) { current += 10; carry = 1; } else { carry = 0; } answer.digit[answer.length++] = current; } while (answer.digit[answer.length] == 0 && answer.length > 1) answer.length--; return answer; } BigInteger BigInteger::operator*(const BigInteger& b){ BigInteger answer; answer.length = length + b.length; for (int i = 0; i < length; ++i) for (int j = 0; j < b.length; ++j) answer.digit[i + j] += digit[i] * b.digit[j]; for (int i = 0; i < answer.length; ++i) { answer.digit[i + 1] += answer.digit[i] / 10; answer.digit[i] %= 10; } while (answer.digit[answer.length] == 0 && answer.length > 1) answer.length--; return answer; } BigInteger BigInteger::operator/(const BigInteger& b){ BigInteger answer; answer.length = length; BigInteger remainder = 0, temp = b; for (int i = length - 1; i >= 0; --i) { if (!(remainder.length == 1 && remainder.digit[0] == 0)) { for (int j = remainder.length - 1; j >= 0; --j) remainder.digit[j + 1] = remainder.digit[j]; remainder.length++; } remainder.digit[0] = digit[i]; while (temp <= remainder) { remainder = remainder - temp; answer.digit[i]++; } } while (answer.digit[answer.length] == 0 && answer.length > 1) answer.length--; return answer; } BigInteger BigInteger::operator%(const BigInteger& b){ BigInteger remainder = 0; BigInteger temp = b; for (int i = length - 1; i >= 0; --i) { if (!(remainder.length == 1 && remainder.digit[0] == 0)) { for (int j = remainder.length - 1; j >= 0; --j) remainder.digit[j + 1] = remainder.digit[j]; remainder.length++; } remainder.digit[0] = digit[i]; while (temp <= remainder) remainder = remainder - temp; } return remainder; }
画⭐的是必写的模板,其他的需要用到才写。
真不知道怎么错的,但是A+B的D进制这一题就是没对。跟书写的一样了,但是不理解代码,只能机械地对比,可能书上也有小错误,但是我没发现了。
#include<iostream> #include<algorithm> #include<string.h> #include<string> #include<math.h> #include<vector> using namespace std; const int MAXN = 10000;//定义常量MAXN表示最大位数,即最多能表示的数字位数 struct BigInteger { int digit[MAXN];//用于存储大整数的每一位数字 int length;//表示大整数的位数 BigInteger(); BigInteger(int x);//构造函数,接受一个整数 x 并将其转换为大整数类型 BigInteger(string str);//构造函数,接受一个字符串 str,并将其转换为大整数类型 BigInteger(const BigInteger& b);//构造函数,接受另外一个大整数类型的对象 b,并将其复制为新的大整数类型 BigInteger operator=(int x);//重载赋值运算符,将一个整数类型的值赋值给大整数类型对象 BigInteger operator=(string str);//重载赋值运算符,将一个字符串类型的值赋值给大整数类型对象 BigInteger operator=(const BigInteger& b);//重载赋值运算符,将另外一个大整数类型的对象赋值给当前对象 bool operator <= (const BigInteger& b);//判断当前大整数类型对象是否小于等于另外一个大整数类型对象 bool operator == (const BigInteger& b);//判断当前大整数类型对象是否等于另外一个大整数类型对象 bool operator != (const BigInteger& b); BigInteger operator+(const BigInteger& b);//重载加法运算符,实现大整数的 + 法 BigInteger operator-(const BigInteger& b);//重载减法运算符,实现大整数的 - 法 BigInteger operator*(const BigInteger& b);//重载乘法运算符,实现大整数的 * 法 BigInteger operator/(const BigInteger& b);//重载除法运算符,实现大整数的 / 法 BigInteger operator%(const BigInteger& b);//重载取模运算符,实现大整数取模 friend istream& operator>>(istream& in, BigInteger& x);//重载输入运算符,用于将用户输入的字符串或整数转换为大整数类型 friend ostream& operator<<(ostream& out, const BigInteger& x);//重载输出运算符,用于输出大整数类型对象 };//该结构体的作用是用于实现大整数的基本运算,方便用户直接进行大整数的计算 istream& operator>>(istream& in, BigInteger& x) {// string str; in >> str; x = str; return in; } ostream& operator<<(ostream& out, const BigInteger& x) { for (int i = x.length - 1; i >= 0; --i) out << x.digit[i]; return out; } BigInteger::BigInteger() { memset(digit, 0, sizeof(digit)); length = 0; } BigInteger::BigInteger(int x) { memset(digit, 0, sizeof(digit)); length = 0; if (x == 0) digit[length++] = x; while (x != 0) { digit[length++] = x % 10; x /= 10; } } BigInteger::BigInteger(string str){ memset(digit, 0, sizeof(digit)); length = str.size(); for (int i = 0; i < length; ++i) digit[i] = str[length - i - 1] - '0'; } BigInteger::BigInteger(const BigInteger& b){ memset(digit, 0, sizeof(digit)); length = b.length; for (int i = 0; i < length; ++i) digit[i] = b.digit[i]; } BigInteger BigInteger::operator=(int x) { memset(digit, 0, sizeof(digit)); length = 0; if (x == 0) digit[length++] = x; while (x != 0) { digit[length++] = x % 10; x /= 10; } return *this; } BigInteger BigInteger::operator=(string str){ memset(digit, 0, sizeof(digit)); length = str.size(); for (int i = 0; i < length; ++i) digit[i] = str[length - i - 1] - '0'; return *this; } BigInteger BigInteger::operator=(const BigInteger& b){ memset(digit, 0, sizeof(digit)); length = b.length; for (int i = 0; i < length; ++i) digit[i] = b.digit[i]; return *this; } bool BigInteger::operator<=(const BigInteger& b){ if (length < b.length) return true; else if (length > b.length) return false; else for (int i = length - 1; i >= 0; --i) { if (digit[i] == b.digit[i]) continue; else return digit[i] < b.digit[i]; } return true; } bool BigInteger::operator==(const BigInteger& b){ if (length != b.length) return false; else for (int i = length - 1; i >= 0; --i) if (digit[i] != b.digit[i]) return false; return true; } bool BigInteger::operator!=(const BigInteger& b){ if (length != b.length) return true; else for (int i = length - 1; i >= 0; --i) if (digit[i] != b.digit[i]) return true; return false; } BigInteger BigInteger::operator+(const BigInteger& b){ BigInteger answer; int carry = 0; for (int i = 0; i < length || i < b.length; ++i) { int current = carry + digit[i] + b.digit[i]; carry = current / 10; answer.digit[answer.length++] = current % 10; } if (carry != 0) answer.digit[answer.length++] = carry; return answer; } BigInteger BigInteger::operator-(const BigInteger& b){ BigInteger answer; int carry = 0; for (int i = 0; i < length; ++i) { int current = digit[i] - b.digit[i] - carry; if (current < 0) { current += 10; carry = 1; } else { carry = 0; } answer.digit[answer.length++] = current; } while (answer.digit[answer.length] == 0 && answer.length > 1) answer.length--; return answer; } BigInteger BigInteger::operator*(const BigInteger& b){ BigInteger answer; answer.length = length + b.length; for (int i = 0; i < length; ++i) for (int j = 0; j < b.length; ++j) answer.digit[i + j] += digit[i] * b.digit[j]; for (int i = 0; i < answer.length; ++i) { answer.digit[i + 1] += answer.digit[i] / 10; answer.digit[i] %= 10; } while (answer.digit[answer.length] == 0 && answer.length > 1) answer.length--; return answer; } BigInteger BigInteger::operator/(const BigInteger& b){ BigInteger answer; answer.length = length; BigInteger remainder = 0, temp = b; for (int i = length - 1; i >= 0; --i) { if (!(remainder.length == 1 && remainder.digit[0] == 0)) { for (int j = remainder.length - 1; j >= 0; --j) remainder.digit[j + 1] = remainder.digit[j]; remainder.length++; } remainder.digit[0] = digit[i]; while (temp <= remainder) { remainder = remainder - temp; answer.digit[i]++; } } while (answer.digit[answer.length] == 0 && answer.length > 1) answer.length--; return answer; } BigInteger BigInteger::operator%(const BigInteger& b){ BigInteger remainder = 0; BigInteger temp = b; for (int i = length - 1; i >= 0; --i) { if (!(remainder.length == 1 && remainder.digit[0] == 0)) { for (int j = remainder.length - 1; j >= 0; --j) remainder.digit[j + 1] = remainder.digit[j]; remainder.length++; } remainder.digit[0] = digit[i]; while (temp <= remainder) remainder = remainder - temp; } return remainder; } int main() { BigInteger a, b, d; cin >> a >> b >> d; BigInteger n = a + b; vector<BigInteger> jieguo; if (d == 10) { cout << n << endl; return 0; } while (n != 0) { cout << n % d << "这是取余\n"; jieguo.push_back(n % d); cout << n << "这是n\n"; cout << d << "这是d\n"; n = n / d; cout << n << "这是除法\n"; } for (int i = jieguo.size() - 1; i >= 0; --i) { cout << jieguo[i]; } cout << endl; return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏