其他分享
首页 > 其他分享> > 高精度

高精度

作者:互联网

高精度

题目要求:

a) 涉及知识点:数组、流程控制、函数等

b) 要求:用整型数组表示10进制大整数(超过2^32的整数),数组的每个元素存储大整数的一位数字,实现大整数的加减法。

实现细节:

  1. 完全模拟简单计算过程:读入数据,储存数据,处理数据,输出数据

    存储 读入

    这里,根据题目要求,要用整数数组来储存,但是介于整数数组读入困难的问题,应该使用字符串来处理输入,然后再对字符串就行处理输入到整数数组中,读入字符串时,数字最高位在字符串首(下标小的位置)。但是习惯上,下标最小的位置存放的是数字的 最低位,即存储反转的字符串。例下图输入15604121072时,先储存进char数组中,采用字符串读取,然后反转处理成整数存储在整数数组中。image-20220509232149915

    代码实现:

    
    void read(int a[]) {
      static char s[LEN + 1];	//静态
      scanf("%s", s);
    
      clear(a);
    
      int len = strlen(s);
      // 反转
      for (int i = 0; i < len; ++i) a[len - i - 1] = s[i] - '0';
      // 字符转数字
    }
    

    输出

    从后向前找不为零的数,然后按位依次输出即可

    void print(int a[]) {
      int i;
      for (i=LEN-1;i>=1;--i)              //这里判定不能限定为i>=0;这样的话执行完i=-1,会导致无输出
        if (a[i] != 0) break;
      for (; i>=0;--i) 
        putchar(a[i] + '0');
      putchar('\n');
    }
    

    加法:

    按照竖式加法,从最低位开始,将两个加数对应位置上的数值相加,并判断是否达到或超过10 。如果达到,那么处理进位:将更高一位的结果上增加 1,当前位的结果减少10 。(可以考虑取模,和除法,但是不可能出现大于18的情况,所以没必要)

    本题所设定的最大位数为LEN=1000位,但一般令数组的最大长度 LEN 比可能的输入大一些, 然后略去末尾的几次循环,可以省去不少边界情况的处理,故在此循环到 LEN - 1 = 1003 已经足够

    代码:

    void add(int a[], int b[], int c[]) {
      clear(c);
    
      for (int i = 0; i < LEN - 1; ++i) {
        c[i]+=a[i]+b[i];    // 将相应位上的数码相加
        if (c[i] >= 10) {
          c[i + 1]+=1;
          c[i]-=10;
        }
      }
    }
    

    减法:

    判定:先判定前面是否大于后面,如果不大于就换位,同时在前面加负号,

    首先判断位数,位数大的大,然后相等时从最高位向低位判断,如果对应位后大于前,说明传入的第一个数比第二个数小,直接结束.

    int judge(int a[],int b[]){
      int i,j,k;
      //分别最大位
      for(i=LEN-1; i>=0;--i)
        if(a[i]!=0) 
          break;
      
      for(j=LEN-1; j>=0; --j)
        if(b[j] != 0)   break;
      //分别判断
      if(i < j)   
        return 0;
      else if(i>j) 
        return 1;
      for(; i>= 0;--i){
        if(a[i]<b[i]) return 0;
      }
      return 1;
    }
    

    实现:从个位起逐位相减,遇到负的情况则向上一位借 1。

    void sub(int a[], int b[], int c[]) {
      clear(c);
    
      for (int i=0; i<LEN-1; ++i) {
        c[i]+=a[i] - b[i];    // 逐位相减
        if (c[i]< 0) {
          c[i+1]-=1;
          c[i]+=10;
        }
      }
    }
    

    实现程序:

    #include<bits/stdc++.h>
    static const int LEN = 1004;
    
    int a[LEN], b[LEN], c[LEN];
    
    void clear(int a[]) {
      for (int i=0; i<LEN; ++i) 
        a[i] = 0;
    }
    
    void read(int a[]) {
      static char s[LEN + 1];     //静态
      scanf("%s", s);
    
      clear(a);
    
      int len = strlen(s);
       // 反转
      for (int i=0; i<len; ++i) 
        a[len - i - 1] = s[i] - '0';      // s[i] - '0' 就是 s[i] 所表示的数值
    }
    
    void print(int a[]) {
      int i;
      for (i=LEN-1;i>=1;--i)              //这里判定不能限定为i>=0;这样的话执行完i=-1,会导致无输出
        if (a[i] != 0) break;
      for (; i>=0;--i) 
        putchar(a[i] + '0');
      putchar('\n');
    }
    int judge(int a[],int b[]){
      int i,j,k;
      //分别最大位
      for(i=LEN-1; i>=0;--i)
        if(a[i]!=0) 
          break;
      
      for(j=LEN-1; j>=0; --j)
        if(b[j] != 0)   break;
      //分别判断
      if(i < j)   
        return 0;
      else if(i>j) 
        return 1;
      for(; i>= 0;--i){
        if(a[i]<b[i]) return 0;
      }
      return 1;
    }
    void add(int a[], int b[], int c[]) {
      clear(c);
    
      for (int i = 0; i < LEN - 1; ++i) {
        c[i]+=a[i]+b[i];    // 将相应位上的数码相加
        if (c[i] >= 10) {
          c[i + 1]+=1;
          c[i]-=10;
        }
      }
    }
    void sub(int a[], int b[], int c[]) {
      clear(c);
    
      for (int i=0;i<LEN-1;++i) {
        c[i]+=a[i]-b[i];    // 逐位相减
        if (c[i]<0) {
          c[i+1]-=1;
          c[i]+=10;
        }
      }
    }
    int main() {
      printf("Please make sure the first num is larger than the second.\nAnd make sure the maximum number of digits is 1000 \n");
      read(a);  read(b);
    
      printf(" the result of add is: ");
      add(a, b, c);
      print(c);
    
      printf(" the result of sub is: ");
      if(judge(a,b)) sub(a,b,c);
      else {  putchar('-'); sub(b,a,c);}
      
      print(c);
      return 0;
    }
    
    

    d单精度乘法

    实现时注意得两个for循环分别判断,要不然前面进位会对结果产生影响导致错误

    void mul(int a[],int e){
        for(int j=0;j<MAX;j++)
            b[j] *=e;
        for(int j=0;j<MAX;j++)
            if(b[j]>9){
                b[j+1]+=b[j]/10;
                b[j]%=10;
            }
        
    }
    

标签:10,高精度,int,void,LEN,--,数组
来源: https://www.cnblogs.com/abldy/p/16348498.html