• C++中如何处理超长的数字(long long类型的整数都无法存储的)


    C++中如何处理超长的数字(long long类型的整数都无法存储的)

    在 C++中,如果数字超出了 long long 类型的范围,可以考虑使用字符串或第三方库(如 Boost.Multiprecision)来表示和处理超长数字。要使用第三方库需要下载并安装所需的第三方库,在此就不介绍了。

    在此介绍使用字符串表示和处理超长数字。本文将介绍使用C++字符串实现超长的数字加法、减法、乘法和除法运算。

    1.判断一个非负的超大数是奇数还是偶数,源码如下:

    1. #include
    2. #include
    3. using namespace std;
    4. int main() {
    5. //string s = "123456789123456789123456789";
    6. cout << "请输入一个正整数:" << endl;
    7. cin >> s;
    8. // s.size()是字符串的长度,即由多少字符组成的, 字符串的最后一位字符即s[s.size() - 1]
    9. char c = s[s.size() - 1];
    10. cout << "最后一位数字是" << c << endl;
    11. // 将一个整数数字字符变成整数,我们只需要将它减字符'0'
    12. int i = c - '0';
    13. if (i % 2 == 0) {
    14. cout << s << "是偶数";
    15. } else {
    16. cout << s << "是奇数";
    17. }
    18. return 0;
    19. }

    2.判断两个超大正整数的大小

    1. #include
    2. #include
    3. using namespace std;
    4. bool Lower(string str1, string str2){
    5. //长度长的一定大(这里假设除了0以外,都没有前导0),长度相等则字典序小的数字更小
    6. return str1.size()size()||(str1.size()==str2.size()&&str1
    7. }
    8. int main() {
    9. cout << "请输入两个超大正整数:" << endl;
    10. string a, b;
    11. cin >> a >> b;
    12. if (Lower(a, b)){
    13. cout << a << "小于" << b << endl;
    14. }
    15. else{
    16. cout << a << "大于" << b << endl;
    17. }
    18. return 0;
    19. }

    下面分别介绍加法、减法、乘法和除法运算的实现方法。特别说明,加减运算仅限非负整数的运算,因为负数的加减运算可以等价为某种形式的加法或者减法运算,故不做考虑;乘除运算只考虑大整数运算,不考虑小数的计算;除法只考虑大整数运算,计算结果精确到6位小数(6位小数后直接舍去)。

    参考https://blog.songjiahao.com/archives/382

    3. 非负大整数的加法

    大数加法的实现,模仿了我们列竖式的计算方法,从个位开始,一位一位的相加,每次考虑进位即可。由于读入的字符串0号位置为最高位,所以我们采用逆序的办法访问字符串,然后每位计算即可。同样的,因为计算时候得到的每一位都是逆序的,最后的结果要进行逆置。

    加法,可能导致最终位数多一位(最高位的进位),所以要记得处理。

    最后,我们来考虑一些特殊情况,比如两个数字都是0,或者其中有一个是0,我们就可以快速得到结果,省去了遍历过程。

    实现代码

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. //判断是否为0,全部为0的数字就是0,比如00000
    6. bool CheckZero(const string &str){ //检查是否等于0
    7. int size=str.size(); //如果全是0则为0,这里假设不会有带符号的+00000或者-00000作为输入
    8. for(int i=0;i
    9. if(str[i]!='0') return false;
    10. return true;
    11. }
    12. string Add(string str1, string str2){
    13. //关于0的处理
    14. if(CheckZero(str1)&&CheckZero(str2)) return "0"; //如果都是0
    15. else if(CheckZero(str1)) return str2; //如果有个一为0
    16. else if(CheckZero(str2)) return str1;
    17. string ans;
    18. int i=str1.size()-1,j=str2.size()-1;
    19. int flag=0; //进位标记
    20. while(i>=0||j>=0||flag){
    21. int numa=i>=0?str1[i--]-'0':0; //如果所有位都访问完毕,对应的位置用0代替
    22. int numb=j>=0?str2[j--]-'0':0;
    23. flag=numa+numb+flag; //计算两位的和
    24. ans+='0'+flag%10; //取个位保存在答案中
    25. flag/=10; //计算进位
    26. }
    27. reverse(ans.begin(),ans.end());
    28. return ans;
    29. }
    30. int main(){
    31. cout << "请输入两个正整数:" << endl;
    32. string a, b;
    33. cin >> a >> b;
    34. string result = Add(a, b);
    35. cout << "和:" << result << endl;
    36. return 0;
    37. }

    4. 非负大整数的减法

    大数减法的实现,也模仿了我们列竖式的计算方法。从个位起,每次计算一位,首先根据后一位是否借位,先减去借位,然后判断当前位是否够减,如果需要借位,则向前一位借位后在减,直到运算完毕。同样的,因为我们要从个位开始计算,所以计算得到的结果必然是逆序的,最终要记得将结果逆置。

    减法,可能出现前导0,要记得清除前导零。

    最后,我们来考虑一些特殊情况,比如两个数相同或者有一个数字为0,我们可以直接得到结果,从而避免了复杂的处理过程。

    实现代码

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. //判断两个超大正整数的大小
    6. bool Lower(string str1, string str2){
    7. //长度长的一定大(这里假设除了0以外,都没有前导0),长度相等则字典序小的数字更小
    8. return str1.size()size()||(str1.size()==str2.size()&&str1
    9. }
    10. //判断是否为0,全部为0的数字就是0,比如00000
    11. bool CheckZero(const string &str){ //检查是否等于0
    12. int size=str.size(); //如果全是0则为0,这里假设不会有带符号的+00000或者-00000作为输入
    13. for(int i=0;i
    14. if(str[i]!='0') return false;
    15. return true;
    16. }
    17. string Sub(string str1, string str2){
    18. //处理0的情况
    19. if(str1==str2||(CheckZero(str1)&&CheckZero(str2))) return "0"; //如果两数相等或者都是0
    20. else if(CheckZero(str1)) return "-"+str2; //如果第一个数字为0
    21. else if(CheckZero(str2)) return str1; //如果第二个数字为0
    22. //定正负
    23. int negative=0; //结果的正负号
    24. if(Lower(str1,str2)){
    25. swap(str1,str2); //保证str1大于str2
    26. negative=1; //如果str1小于str2,则结果过为负值
    27. }
    28. string ans;
    29. int i=str1.size()-1,j=str2.size()-1;//逆序开始处理
    30. int flag=0; //借位标记
    31. while(i>=0||j>=0){
    32. int numa=i>=0?str1[i--]-'0':0; //取每一位,因为长度可能不同所以当某一个已经读取完毕时对应位置取0
    33. int numb=j>=0?str2[j--]-'0':0;
    34. numa-=flag; //先减去借位
    35. if(numa//如果不够减则向上一位借位(只可能借一位)
    36. numa+=10; //借位并记录借位
    37. flag=1;
    38. }
    39. else flag=0; //如果不借位,则借位标记为0
    40. ans+='0'+numa-numb; //计算当前位置并保存
    41. }
    42. i=ans.size()-1;
    43. while(ans[i]=='0') i--;
    44. ans=ans.substr(0,i+1); //去除前导0,如111-110=1
    45. if(negative) ans+='-'; //如果计算结果是负数,添加负数符号
    46. reverse(ans.begin(),ans.end()); //因为是逆序计算得到的结果,所以需要翻转一下
    47. return ans;
    48. }
    49. int main(){
    50. cout << "请输入两个正整数:" << endl;
    51. string a, b;
    52. cin >> a >> b;
    53. string result = Sub(a, b);
    54. cout << "差: " << result << endl;
    55. return 0;
    56. }

    5.大整数的乘法

    大数乘法的实现,还采用我们竖式计算的方法。从个位开始,每次计算被乘数和乘数一位的积,然后借助我们写好的大数加法实现最终结果的累加。但是大数乘法需要考虑正负的问题,所以需要对正负号进行处理,对两个数的符号使用异或最终可以确定乘积结果的正负。

    乘法,因为乘数的每一位都有相应的权值(个十百千万),因此我们对于乘数每一位的积进行运算时要考虑该位置的权值,在积的后边补充相应个数的零即可。

    最后,我们考虑一些特殊情况,比如两个数字中只要有一个是0,则结果就是0。

    实现代码

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. //判断两个超大正整数的大小
    6. bool Lower(string str1, string str2){
    7. //长度长的一定大(这里假设除了0以外,都没有前导0),长度相等则字典序小的数字更小
    8. return str1.size()size()||(str1.size()==str2.size()&&str1
    9. }
    10. //判断是否为负,只需要判断第一位是不是负号即可,这里不考虑正号的存在,即认为不使用正号
    11. bool CheckNegative(const string &str){ //检查是否为负数
    12. return str[0]=='-';
    13. }
    14. //判断是否为0,全部为0的数字就是0,比如00000
    15. bool CheckZero(const string &str){ //检查是否等于0
    16. int size=str.size(); //如果全是0则为0,这里假设不会有带符号的+00000或者-00000作为输入
    17. for(int i=0;i
    18. if(str[i]!='0') return false;
    19. return true;
    20. }
    21. string Add(string str1, string str2){
    22. //关于0的处理
    23. if(CheckZero(str1)&&CheckZero(str2)) return "0"; //如果都是0
    24. else if(CheckZero(str1)) return str2; //如果有个一为0
    25. else if(CheckZero(str2)) return str1;
    26. string ans;
    27. int i=str1.size()-1,j=str2.size()-1;
    28. int flag=0; //进位标记
    29. while(i>=0||j>=0||flag){
    30. int numa=i>=0?str1[i--]-'0':0; //如果所有位都访问完毕,对应的位置用0代替
    31. int numb=j>=0?str2[j--]-'0':0;
    32. flag=numa+numb+flag; //计算两位的和
    33. ans+='0'+flag%10; //取个位保存在答案中
    34. flag/=10; //计算进位
    35. }
    36. reverse(ans.begin(),ans.end());
    37. return ans;
    38. }
    39. string Mul(string str1, string str2){
    40. if(CheckZero(str1)||CheckZero(str2)) return "0"; //如果有一个为0,则结果为0
    41. int negative=0,negastr1=0,negastr2=0; //定正负
    42. if(CheckNegative(str1)){ //确定正负号标记,并且去掉-字符
    43. negastr1=1; str1=str1.substr(1,str1.size()-1);
    44. }
    45. if(CheckNegative(str2)){
    46. negastr2=1; str2=str2.substr(1,str2.size()-1);
    47. }
    48. negative=negastr1^negastr2; //异或运算确定结果的正负号
    49. string ans;
    50. if(Lower(str1,str2)) swap(str1,str2); //保证str1大于等于str2
    51. int size1=str1.size(),size2=str2.size();
    52. for(int i=size2-1;i>=0;i--){ //遍历较小数字的每一位
    53. string temp(size2-1-i,'0'); //temp为str1乘以str2[i]的积,根据str2[i]的权重(个十百千万,补充对应个数的0)
    54. int flag=0; //进位标记
    55. for(int j=size1-1;j>=0;j--){ //temp
    56. flag+=(str1[j]-'0')*(str2[i]-'0');
    57. temp.push_back('0'+(flag%10));
    58. flag/=10;
    59. }
    60. if(flag) temp.push_back('0'+flag); //如果最高位还有进位
    61. reverse(temp.begin(),temp.end());
    62. ans=Add(ans,temp); //将计算结果累加到最终的结果上
    63. }
    64. if(negative) ans="-"+ans; //处理结果的正负号
    65. return ans;
    66. }
    67. int main(){
    68. cout << "请输入两个整数:" << endl;
    69. string a, b;
    70. cin >> a >> b;
    71. string result = Mul(a, b);
    72. cout << "积:" << result << endl;
    73. return 0;
    74. }

    6. 大整数的除法,计算结果精确到6位小数(6位小数后直接舍去)

    如商3.700014[5800933124]

    大数除法的实现,同样采用我们除法式子的方法进行计算。首先,使用异或的方法确定结果的正负号。两个数字相除的时候,如果第一个数字大于等于第二个数字,则结果一定是大于等于1的,否则小于1。于是,为了实现小于1的结果表示,我们为结果精确到小数点后6位。这里采用的方法为:事先确定是否为纯小数,然后在第一个数字的末尾加上6个0,然后使用我们除法式子的方法进行计算。从第一个数字的头部开始,找到第一个长度能够进行商运算的数字开始,计算商并将临时的余数补足一位进行下一位商的计算,直到计算完毕。

    除法,可能遇到除数为0的情况,因此需要在计算的时候提前进行判定。另外计算过程中,计算商的方法使用大数的减法操作,因此可能会遇到0堆积的情况(长度增大),会影响到大小的比较判定,要注意处理。

    最后,我们考虑一些特殊情况,比如被除数为0的时候,可以直接输出结果0.000000。

    实现代码

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. //判断两个超大正整数的大小
    6. bool Lower(string str1, string str2){
    7. //长度长的一定大(这里假设除了0以外,都没有前导0),长度相等则字典序小的数字更小
    8. return str1.size()size()||(str1.size()==str2.size()&&str1
    9. }
    10. //判断是否为负,只需要判断第一位是不是负号即可,这里不考虑正号的存在,即认为不使用正号
    11. bool CheckNegative(const string &str){ //检查是否为负数
    12. return str[0]=='-';
    13. }
    14. //判断是否为0,全部为0的数字就是0,比如00000
    15. bool CheckZero(const string &str){ //检查是否等于0
    16. int size=str.size(); //如果全是0则为0,这里假设不会有带符号的+00000或者-00000作为输入
    17. for(int i=0;i
    18. if(str[i]!='0') return false;
    19. return true;
    20. }
    21. //大数减法
    22. string Sub(string str1, string str2){
    23. //处理0的情况
    24. if(str1==str2||(CheckZero(str1)&&CheckZero(str2))) return "0"; //如果两数相等或者都是0
    25. else if(CheckZero(str1)) return "-"+str2; //如果第一个数字为0
    26. else if(CheckZero(str2)) return str1; //如果第二个数字为0
    27. //定正负
    28. int negative=0; //结果的正负号
    29. if(Lower(str1,str2)){
    30. swap(str1,str2); //保证str1大于str2
    31. negative=1; //如果str1小于str2,则结果过为负值
    32. }
    33. string ans;
    34. int i=str1.size()-1,j=str2.size()-1;//逆序开始处理
    35. int flag=0; //借位标记
    36. while(i>=0||j>=0){
    37. int numa=i>=0?str1[i--]-'0':0; //取每一位,因为长度可能不同所以当某一个已经读取完毕时对应位置取0
    38. int numb=j>=0?str2[j--]-'0':0;
    39. numa-=flag; //先减去借位
    40. if(numa//如果不够减则向上一位借位(只可能借一位)
    41. numa+=10; //借位并记录借位
    42. flag=1;
    43. }
    44. else flag=0; //如果不借位,则借位标记为0
    45. ans+='0'+numa-numb; //计算当前位置并保存
    46. }
    47. i=ans.size()-1;
    48. while(ans[i]=='0') i--;
    49. ans=ans.substr(0,i+1); //去除前导0,如111-110=1
    50. if(negative) ans+='-'; //如果计算结果是负数,添加负数符号
    51. reverse(ans.begin(),ans.end()); //因为是逆序计算得到的结果,所以需要翻转一下
    52. return ans;
    53. }
    54. string Div(string str1, string str2){
    55. //处理除数为0的情况和被除数为0的情况
    56. if(CheckZero(str2)) return "The divisor cannot be zero!";
    57. else if(CheckZero(str1)) return "0.000000";
    58. int negative=0,negastr1=0,negastr2=0; //定正负
    59. if(CheckNegative(str1)){ //确定正负号标记,并且去掉-
    60. negastr1=1; str1=str1.substr(1,str1.size()-1);
    61. }
    62. if(CheckNegative(str2)){
    63. negastr2=1; str2=str2.substr(1,str2.size()-1);
    64. }
    65. negative=negastr1^negastr2; //异或运算确定结果的正负号
    66. int point=0; //结果是否为纯小数
    67. if(Lower(str1,str2)) point=1; //如果str1小于str2,则计算为纯小数
    68. string ans; //计算结果
    69. str1+=string(6,'0'); //补足6个0,用于计算小数位
    70. int size1=str1.size(),size2=str2.size();
    71. int i=size2-1; //商第一位的位置
    72. string temp=str1.substr(0,i); //从str1上取size2-1个字符
    73. for(i;i
    74. temp+=str1[i]; //从后边拿出一位,预先处理可以防止结尾处越界
    75. int cnt=0; //当前位的商,也就是temp中包含了多少个str2,使用减法 //如果temp不为0,则计算商
    76. while(Lower(str2,temp)||temp==str2){ //如果当前位商不为0,则计算商
    77. temp=Sub(temp,str2);
    78. cnt++;
    79. }
    80. if(temp=="0") temp.clear(); //如果某次计算结果为0,则清空,避免0的堆积,比如111000 111
    81. ans.push_back('0'+cnt); //保存商
    82. }
    83. i=0;
    84. while(ans[i]=='0') i++;
    85. ans=ans.substr(i,ans.size()-i); //去除前导0
    86. if(point){ //如果是纯小数,补足6位并添加小数点
    87. int len=6-ans.size();
    88. ans="0."+string(len,'0')+ans;
    89. }
    90. else ans.insert((ans.end()-6),'.'); //如果不是小数,则只需要插入小数点
    91. if(negative) ans="-"+ans; //最后一步骤,如果是负数带上负号
    92. return ans;
    93. }
    94. int main(){
    95. cout << "请输入两个整数:" << endl;
    96. string a, b;
    97. cin >> a >> b;
    98. string result = Div(a, b);
    99. cout << "商(6位小数后直接舍去):" << result << endl;
    100. return 0;
    101. }

    7.最后,整合为大数四则运算

    加减运算仅限非负整数的运算,因为负数的加减运算可以等价为某种形式的加法或者减法运算,故不做考虑;乘除运算只考虑大整数运算,不考虑小数的计算;除法只考虑大整数运算,计算结果精确到6位小数(6位小数后直接舍去)。源码如下:

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. //大数四则运算,两个参数都不能为空
    6. string Add(string str1, string str2); //大数加法
    7. string Sub(string str1, string str2); //大数减法
    8. string Mul(string str1, string str2); //大数乘法
    9. string Div(string str1, string str2); //大数除法
    10. bool Lower(string str1, string str2); //大数比较(小于)
    11. bool CheckZero(const string &str); //检查是不是0,比如0000认为是0
    12. bool CheckNegative(const string &str); //检查是不是负数
    13. void ShowMenu(); //提示菜单
    14. void ShowMenu(char choice); //二级菜单
    15. int main(){
    16. string a,b;
    17. char ch;
    18. ShowMenu();
    19. while(cin>>ch&&ch!='q'){ //循环打印菜单并提示用户输入
    20. ShowMenu(ch);
    21. cin>>a>>b;
    22. switch(ch){
    23. case 'a':cout<" + "<" = "<<Add(a,b)<break;
    24. case 'b':cout<" - "<" = "<<Sub(a,b)<break;
    25. case 'c':cout<" * "<" = "<<Mul(a,b)<break;
    26. case 'd':cout<" / "<" = "<<Div(a,b)<break;
    27. }
    28. ShowMenu();
    29. }
    30. return 0;
    31. }
    32. string Add(string str1, string str2){
    33. //关于0的处理
    34. if(CheckZero(str1)&&CheckZero(str2)) return "0"; //如果都是0
    35. else if(CheckZero(str1)) return str2; //如果有个一为0
    36. else if(CheckZero(str2)) return str1;
    37. string ans;
    38. int i=str1.size()-1,j=str2.size()-1;
    39. int flag=0; //进位标记
    40. while(i>=0||j>=0||flag){
    41. int numa=i>=0?str1[i--]-'0':0; //如果所有位都访问完毕,对应的位置用0代替
    42. int numb=j>=0?str2[j--]-'0':0;
    43. flag=numa+numb+flag; //计算两位的和
    44. ans+='0'+flag%10; //取个位保存在答案中
    45. flag/=10; //计算进位
    46. }
    47. reverse(ans.begin(),ans.end());
    48. return ans;
    49. }
    50. string Sub(string str1, string str2){
    51. //处理0的情况
    52. if(str1==str2||(CheckZero(str1)&&CheckZero(str2))) return "0"; //如果两数相等或者都是0
    53. else if(CheckZero(str1)) return "-"+str2; //如果第一个数字为0
    54. else if(CheckZero(str2)) return str1; //如果第二个数字为0
    55. //定正负
    56. int negative=0; //结果的正负号
    57. if(Lower(str1,str2)){
    58. swap(str1,str2); //保证str1大于str2
    59. negative=1; //如果str1小于str2,则结果过为负值
    60. }
    61. string ans;
    62. int i=str1.size()-1,j=str2.size()-1;//逆序开始处理
    63. int flag=0; //借位标记
    64. while(i>=0||j>=0){
    65. int numa=i>=0?str1[i--]-'0':0; //取每一位,因为长度可能不同所以当某一个已经读取完毕时对应位置取0
    66. int numb=j>=0?str2[j--]-'0':0;
    67. numa-=flag; //先减去借位
    68. if(numa//如果不够减则向上一位借位(只可能借一位)
    69. numa+=10; //借位并记录借位
    70. flag=1;
    71. }
    72. else flag=0; //如果不借位,则借位标记为0
    73. ans+='0'+numa-numb; //计算当前位置并保存
    74. }
    75. i=ans.size()-1;
    76. while(ans[i]=='0') i--;
    77. ans=ans.substr(0,i+1); //去除前导0,如111-110=1
    78. if(negative) ans+='-'; //如果计算结果是负数,添加负数符号
    79. reverse(ans.begin(),ans.end()); //因为是逆序计算得到的结果,所以需要翻转一下
    80. return ans;
    81. }
    82. string Mul(string str1, string str2){
    83. if(CheckZero(str1)||CheckZero(str2)) return "0"; //如果有一个为0,则结果为0
    84. int negative=0,negastr1=0,negastr2=0; //定正负
    85. if(CheckNegative(str1)){ //确定正负号标记,并且去掉-字符
    86. negastr1=1; str1=str1.substr(1,str1.size()-1);
    87. }
    88. if(CheckNegative(str2)){
    89. negastr2=1; str2=str2.substr(1,str2.size()-1);
    90. }
    91. negative=negastr1^negastr2; //异或运算确定结果的正负号
    92. string ans;
    93. if(Lower(str1,str2)) swap(str1,str2); //保证str1大于等于str2
    94. int size1=str1.size(),size2=str2.size();
    95. for(int i=size2-1;i>=0;i--){ //遍历较小数字的每一位
    96. string temp(size2-1-i,'0'); //temp为str1乘以str2[i]的积,根据str2[i]的权重(个十百千万,补充对应个数的0)
    97. int flag=0; //进位标记
    98. for(int j=size1-1;j>=0;j--){ //temp
    99. flag+=(str1[j]-'0')*(str2[i]-'0');
    100. temp.push_back('0'+(flag%10));
    101. flag/=10;
    102. }
    103. if(flag) temp.push_back('0'+flag); //如果最高位还有进位
    104. reverse(temp.begin(),temp.end());
    105. ans=Add(ans,temp); //将计算结果累加到最终的结果上
    106. }
    107. if(negative) ans="-"+ans; //处理结果的正负号
    108. return ans;
    109. }
    110. string Div(string str1, string str2){
    111. //处理除数为0的情况和被除数为0的情况
    112. if(CheckZero(str2)) return "The divisor cannot be zero!";
    113. else if(CheckZero(str1)) return "0.000000";
    114. int negative=0,negastr1=0,negastr2=0; //定正负
    115. if(CheckNegative(str1)){ //确定正负号标记,并且去掉-
    116. negastr1=1; str1=str1.substr(1,str1.size()-1);
    117. }
    118. if(CheckNegative(str2)){
    119. negastr2=1; str2=str2.substr(1,str2.size()-1);
    120. }
    121. negative=negastr1^negastr2; //异或运算确定结果的正负号
    122. int point=0; //结果是否为纯小数
    123. if(Lower(str1,str2)) point=1; //如果str1小于str2,则计算为纯小数
    124. string ans; //计算结果
    125. str1+=string(6,'0'); //补足6个0,用于计算小数位
    126. int size1=str1.size(),size2=str2.size();
    127. int i=size2-1; //商第一位的位置
    128. string temp=str1.substr(0,i); //从str1上取size2-1个字符
    129. for(i;i
    130. temp+=str1[i]; //从后边拿出一位,预先处理可以防止结尾处越界
    131. int cnt=0; //当前位的商,也就是temp中包含了多少个str2,使用减法 //如果temp不为0,则计算商
    132. while(Lower(str2,temp)||temp==str2){ //如果当前位商不为0,则计算商
    133. temp=Sub(temp,str2);
    134. cnt++;
    135. }
    136. if(temp=="0") temp.clear(); //如果某次计算结果为0,则清空,避免0的堆积,比如111000 111
    137. ans.push_back('0'+cnt); //保存商
    138. }
    139. i=0;
    140. while(ans[i]=='0') i++;
    141. ans=ans.substr(i,ans.size()-i); //去除前导0
    142. if(point){ //如果是纯小数,补足6位并添加小数点
    143. int len=6-ans.size();
    144. ans="0."+string(len,'0')+ans;
    145. }
    146. else ans.insert((ans.end()-6),'.'); //如果不是小数,则只需要插入小数点
    147. if(negative) ans="-"+ans; //最后一步骤,如果是负数带上负号
    148. return ans;
    149. }
    150. bool Lower(string str1, string str2){ //长度长的一定大(这里假设除了0以外,都没有前导0),长度相等则字典序小的数字更小
    151. return str1.size()size()||(str1.size()==str2.size()&&str1
    152. }
    153. bool CheckZero(const string &str){ //检查是否等于0
    154. int size=str.size(); //如果全是0则为0,这里假设不会有带符号的+00000或者-00000作为输入
    155. for(int i=0;i
    156. if(str[i]!='0') return false;
    157. return true;
    158. }
    159. bool CheckNegative(const string &str){ //检查是否为负数
    160. return str[0]=='-';
    161. }
    162. void ShowMenu(){
    163. cout<<"请选择要进行的大数运算:\n"
    164. <<"a) 加法 b) 减法\n"
    165. <<"c) 乘法 d) 除法\n"
    166. <<"q) 退出\n"
    167. <<"请输入你的选择: ";
    168. }
    169. void ShowMenu(char choice){
    170. cout<<"请输入要计算的两个数字";
    171. switch(choice){
    172. case 'a':cout<<"(仅支持非负整数加法计算): "<break;
    173. case 'b':cout<<"(仅支持非负整数减法计算): "<break;
    174. case 'c':cout<<"(仅支持整数乘法计算): "<break;
    175. case 'd':cout<<"(仅支持整数除法计算,计算结果保留6位小数,之后的直接舍弃): "<break;
    176. }
    177. }

    附录、进一步学习了解

    https://blog.csdn.net/weixin_44668898/article/details/96763177

    https://blog.csdn.net/wyqxii/article/details/131965735

  • 相关阅读:
    胖小酱为什么天上会打雷?
    【Vue十二】--- 指令
    力扣刷题-哈希表-三数之和
    【DR_CAN-MPC学习笔记】3.一个详细的建模例子
    FSDP(Fully Sharded Data Parallel)
    vue3按需引入 vite-plugin-style-import 2.0版本报错(解决办法)
    【力扣练习】找一个字符串中不含有重复字符的最长字串的长度
    [激光原理与应用-34]:《光电检测技术-1》- 光学测量基础 - 光电检测、光学测量、作用、应用、发展趋势
    VS2019编译配置Easy3D
    VirtualBox网络连接方式学习笔记
  • 原文地址:https://blog.csdn.net/cnds123/article/details/132858897