高精度

高精度算法

学习并记录一下自己的见解,所有代码均摘自看了理解以后再抄 代号4101(顺便一提这个佬写的模板理解了真的很好用,两个构造函数使得int和char可以直接赋值 给结构体bign,还有几乎所有基本要用的运算符号都重载了。)我下面写一下大佬的代码片段说一下对大数运算的理解。

基本结构

 #include<bits/stdc++.h>
 using namespace std;
 #define abc(i,j,k) for(int i=(int)(j);i<=(int)(k);i++)
 #define cba(i,j,k) for(int i=(int)(j);i>=(int)(k);i--)
 const int maxn = 5000;
 struct bignum
 {
      int d[maxn],len;
      void clean(){
          while(len > 1 && !d[len-1])//不能等于1,若等于1当数为0时数组长度就为0了
              len--;
      }
      bignum() {
          memset(d,0,sizeof(d));
          len=1;
      }
      bignum(int num) {*this = num;}
      bignum(char* num){*this = num;}
      bool operator <(const bignum& b) const{
      if(len != b.len) return len < b.len;
        for(int i = len-1; i >= 0; i--)
            if(d[i] != b.d[i]) return d[i] < b.d[i];
      return false;
      }
      string str() const{
        char s[maxn]={};
        abc(i,0,len-1)s[len-1-i]=d[i]+'0';
        return s;
    }
 }

高精度加法

一位一位对着加,把进位储存,以便进行下一位的运算。最后判断一下原最高位是否产生进位即可。

bignum operator + (const bignum& b){
          bignum c = *this;
          int L;
          abc(i,0,b.len-1){//for循环
              c.d[i] += b.d[i];
              if(c.d[i]>9)
              {
                 c.d[i]%=10;
                 c.d[i+1]++;
              }
          }
          L=b.len;
          while(c.d[L]>9)//较小的数加完后处理大数的高位进位
          {//比如9999999+1
              c.d[L++]%=10;
              c.d[L]++;
          }
          c.len=max(len,b.len);
          if(c.d[L] && c.len<=L) c.len = L + 1;//最高位进位后长度加一
          return c;
      }

高精度减法

原理和加法基本相同,多了一个清除高位多余的零,少了最高位进位后加一

bignum operator - (const bignum& b){
          bignum c = *this;
          int L; 
          abc(i,0,b.len-1){
              c.d[i] -= b.d[i];
              if(c.d[i] < 0){
                  c.d[i]+=10;
                  c.d[i+1]--;//向前借位
              }
          }
          L=b.len;
          while(c.d[L] < 0){
              c.d[L++]+=10;
              c.d[L]--;
          }
          c.clean();//清除高位前面多余的零
          return c;
      }   

高精度乘法

这个原理就是竖式计算,先是下边数的个位×上边数的每一位(不要进位,到最后会处理)之后十位,百位以此类推。
乘法这里有一个我没有理解的就是函数名称后面的const的作用,少了的话大数×int类型会报错 ,加上则不会报错。留坑后填,绝对不鸽

bignum operator * (const bignum &b)const{//竖式计算原理
          bignum c;
          c.len = len + b.len ;
          abc(j,0,b.len-1)
             abc(i,0,len-1)
                c.d[i+j] += d[i] * b.d[j];//上面说的过程
          abc(i,0,c.len-2)
          {
              c.d[i+1] += c.d[i]/10;//向高位进位
              c.d[i] %= 10;
          }
          c.clean();//清除高位零
          return c;
      }

高精度除法

我个人感觉这个是最难搞的一个,好像也是类似除法的竖式运算,先取一个a=0,进入第一次循环,a=当前最高位,再用循环0-9判断j取何值时满足a<b*(j+1),后取j为除数(会出现高位0的情况,所以最后要清除高位0),后a对b取余(a=a-b*j),进入第二次循环,a*10+最高位的下一位,以此类推。

bignum operator / (const bignum& b){
          bignum c = *this;
          bignum a = 0;
          int j;
          cba(i,len-1,0)//从高位到低位取数
          {
              a = a*10 + d[i];
              for(j = 0;j < 10;j++)if(a < b*(j+1))break;
              c.d[i] = j;
              a = a - b*j;//a对b取余
          }
          c.clean();//清除高位0
          return c;
      }

高精度模

上面除法最后一次循环得到的a就为余数,较为简单

bignum operator % (const bignum &b){
          bignum a = 0;
          int j;
          cba(i,len-1,0)
          {
              a = a*10 + d[i];
              for(j = 0;j < 10;j++)if(a < b*(j+1))break;
              a = a - b*j;//余数
          }
          return a;
      }

剩下的就是重载输入输出了我就不贴上去了,刚刚开始写博客没多久 ,可能版面较乱,讲解过乱,总之就是太菜了 ,希望不要嫌弃。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值