zoukankan      html  css  js  c++  java
  • 高精度运算模板(cpp)

    c++实现高精度四则运算

    总概

    由于c++没有像pythonjava等语言对一些超大整数的处理机制--(java中的大整数类啊,python中默认整数位数就可以无限大);所以,在对于一个c++学习者来说,对这类大整数的运算的掌握很有必要。同样,这也是对我们将人类模拟转化为代码语言的能力的一种提升。

    所以:在此,给各位看官总结了四类高精度运算的处理方式:

    1. 高精度加法(两个大整数相加,所谓大整数,指其位数最高可达10^5)

    2. 高精度减法(两个大整数相减)

    3. 高精度乘法(大整数与一个小整数相乘)

    4. 高精度除法(大整数除以一个小整数)


    高精度加法

     //高精度加法
     #include<vector>
     #include<cstdio>
     #include<cstring>
     #include<iostream>
     #include<algorithm>
     using namespace std;
     
     vector<int> add(vector<int> & a,vector<int> & b){
      vector<int>sum;
     
      int t = 0;//用来保存进位
      for(int i=0;i<a.size() || i<b.size();i++){
      if(i < a.size()) t += a[i];
      if(i < b.size()) t += b[i];
      sum.push_back(t%10);
      t/=10;
      }
      if(t != 0) sum.push_back(t);
      return sum;
     }
     int main(){
      string a,b;
      cin>>a>>b;
      vector<int>A,B;
         //我们输入时默认数据高位会在字符串低索引位置,但在这里我们采用低索引位置存储数据的低位。方便后续处理进位。
      for(int i=a.size()-1;i>=0;i--) A.push_back(a[i] - '0');
      for(int i=b.size()-1;i>=0;i--) B.push_back(b[i] - '0');
     
      auto C = add(A,B);
     
      for(int i=C.size()-1;i>=0;i--) printf("%d",C[i]);
      return 0;
     }
     

    高精度减法

     //高精度减法
     #include<vector>
     #include<cstdio>
     #include<cstring>
     #include<iostream>
     #include<algorithm>
     using namespace std;
     
     string a,b;
     bool cmp(vector<int>&a,vector<int>&b){
      //判断a表示的数是否大于b
      //1、比较位数
      if(a.size()!=b.size()) return a.size()>b.size();
      //2、位数相同则 从高位依次比位数大小
      for(int i=a.size()-1;i>=0;i--){
      if(a[i] != b[i]) return a[i] > b[i];
      }
      //最后如果两个数相同,返回真.注意,不能返回假,否则输出结果时回输出“-0”而不是“0”
      return true;
     }
     
     vector<int> sub(vector<int> & a,vector<int> & b){
      vector<int>C;
      for(int i=0,t=0;i<a.size();i++){
      t = a[i] - t;
      if(i<b.size()) t -= b[i];
      C.push_back((t+10) % 10);
      if(t<0) t=1;
      else t=0;
      }
      //现在C中存的是结果了,但我们还要去掉前导0,符合人们阅读习惯
      while(C.size() > 1 && C.back()==0){
      C.pop_back();
      }
      return C;
     }
     int main(){
      cin>>a>>b;
      vector<int>A,B;
      for(int i=a.size()-1;i>=0;i--) A.push_back(a[i] - '0');
      for(int i=b.size()-1;i>=0;i--) B.push_back(b[i] - '0');
     
      if(cmp(A,B)){//判断A表示的数是否大于B
      auto C = sub(A,B);
      for(int i=C.size()-1;i>=0;i--) printf("%d",C[i]);
      }else{
      auto C = sub(B,A);
      printf("-");
      for(int i=C.size()-1;i>=0;i--) printf("%d",C[i]);
      }
      return 0;
     }

    高精度乘法

     //高精度乘法
     #include<vector>
     #include<cstdio>
     #include<cstring>
     #include<iostream>
     #include<algorithm>
     using namespace std;
     
     vector<int> mul(vector<int>& a,int b){
      vector<int>c;
      int t=0;
      //条件加上"||t"是要处理大整数a运算完成过后t可能有多位尚未存入c中。待t的每一位都存入c中才跳出循环。
      for(int i=0;i<a.size() || t;i++){
      t += a[i] * b;
      c.push_back(t%10);
      t /= 10;
      }
     
      //去前导0
      while(c.size()>1 && c.back()==0){
      c.pop_back();
      }
      return c;
     }
     int main(){
      //a表示大整数
      string a;
      //b表示小整数
      int b;
      cin>>a>>b;
      vector<int> A;
      for(int i=a.size()-1;i>=0;i--) A.push_back(a[i] - '0');
     
      auto C = mul(A,b);
     
      for(int i=C.size()-1;i>=0;i--) printf("%d",C[i]);
      return 0;
     }

    高精度除法

     //高精度除法
     #include<vector>
     #include<cstdio>
     #include<cstring>
     #include<iostream>
     #include<algorithm>
     using namespace std;
     
     vector<int> div(vector<int> & a,int b,int & r){
      //余数以引用形式返回
      vector<int>c;
      //余数初始为0
      r = 0;
      for(int i=a.size()-1;i>=0;i--){
      //上一位的余数*10 + 本位数值 -- 模拟human处理除法运算
      r = r * 10 + a[i];
      c.push_back(r/b);
      r %= b;
      }
     
      //除法运算完成后,商的存储是高位在低索引位置,为了我们总结的四类高精度运算的统一,我们把存商的容器倒置
      reverse(c.begin(),c.end());//注意,包含algorithm头文件
     
      //去前导0
      while(c.size()>1 && c.back()==0) c.pop_back();
     
      return c;
     }
     int main(){
      vector<int>A;
      //大整数a
      string a;
      //小整数b及最后的余数r
      int b,r;
      cin>>a>>b;
      for(int i=a.size()-1;i>=0;i--) A.push_back(a[i] - '0');
     
      auto C = div(A,b,r);
     
      for(int i=C.size()-1;i>=0;i--) printf("%d",C[i]);
     
      //输出余数
      cout<<endl<<r<<endl;
     
      return 0;
     }

    到这里,大家可以去了解一下计组中的补码四则运算,与我们总结的四类算法模板有些许相似之处。并且,通过本次总结,收获也是颇多,我们可以通过自己对算法的设计来完成一些语言本身难以实现的超大数据的处理。

     

     

  • 相关阅读:
    c语言数组指针
    (4)activiti工作流引擎之uel表达式
    (3)activiti流程的挂起和激活
    (2)java程序走一遍工作流activiti
    (1)activiti认识以及数据库和插件配置
    linux 下路由配置
    lvs-dr+keepalived
    LVS-DR 配置测试
    简单认识TCP/IP协议
    mysql 主从同步-读写分离
  • 原文地址:https://www.cnblogs.com/yuanshixiao/p/14616344.html
Copyright © 2011-2022 走看看