【算法】高精度算法讲解

来源:互联网 发布:算法导论 第三版 编辑:程序博客网 时间:2024/06/05 22:37

1.概念

高精度运算,是指参与运算的数(加数,减数,因子……)范围大大超出了标准数据类型(整型,实型)能表示的范围的运算。例如,求两个200位的数的和。这时,就要用到高精度算法了

高精度使用数组来存储整数,模拟手算进行四则运算

2.高精度运算涉及到的问题

(1) 数据的输入

(2) 数据的存储

(3)数据的运算:进位和借位

 (4)结果的输出:小数点的位置和处于多余的0

3.高精度加法

#include<iostream>#include<cstdio>#include<cstring>using namespace std;int main(){char a1[100],b1[100];int a[100],b[100],c[100];int lena,lenb,lenc,i,x; 注意x是Int型memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); memset(c,0,sizeof(c)); gets(a1);  gets(b1); //输入加数与被加数  lena=strlen(a1);  lenb=strlen(b1);  for (i=0;i<=lena-1;i++)    a[lena-i]=a1[i]-48; //加数放入a数组    for (i=0;i<=lenb-1;i++)     b[lenb-i]=b1[i]-48; //加数放入b数组  lenc =1; x=0;  while (lenc <=lena||lenc <=lenb) {     c[lenc]=a[lenc]+b[lenc]+x; //两数相加    x=c[lenc]/10;    c[lenc]%=10;   lenc++; } c[lenc]=x; if (c[lenc]==0)//此时最高位上的加法 例如9+3 = 12 要溢出一位    lenc--; //处理最高进位 for (i=lenc;i>=1;i--)  cout<<c[i]; //输出结果 cout<<endl;return 0; }

4.高精度减法

 
  和高精度加法相比,减法在差为负数时处理的细节更多一点:当被减数小于减数时,差为负数,差的绝对值是减数减去被减数;在程序实现上用一个变量来存储符号位,用另一个数组存差的绝对值。
  算法流程:
(1)读入被减数S1,S2(字符串);
(2)置符号位:判断被减数是否大于减数:大则将符号位置为空;小则将符号位置为“-”,交换减数与被减数;
(3)被减数与减数处理成数值,放在数组中;
(4)运算:
    A、取数;
    B、判断是否需要借位;
   C、减,将运算结果放到差数组相应位中;
   D、判断是否运算完成:是,转5;不是,转A;
(5)打印结果:符号位,第1位,循环处理第2到最后一位;

    #include<stdio.h>    #include<string.h>        void exch_str(char*s1, char*s2)//当减数大于被减数 交换二者 eg:2 -3 减数为3     {        char tmp[1001];        strcpy(tmp,s1);        strcpy(s1,s2);        strcpy(s2,tmp);    }        int a1[1001],b1[1001],s[1001];         int main()    {        char a[1001], b[1001];        int sign=1;        int len_a, len_b, i, j, k=0, t;        scanf("%s %s", a, b);        len_a = strlen(a);        len_b = strlen(b);        if(len_a < len_b)        {            sign = -1;//符号位置负            exch_str(a,b);//交换被减数与减数            t = len_a;            len_a = len_b;            len_b = t;//交换他们的长度        }        else if(len_a == len_b)          for(i = 0; i < len_a; ++i)            if(a[i] > b[i])            {              sign = 1;              break;            }            else if(a[i] < b[i])//两者长度相同 差仍未负数             {              sign = -1;              exch_str(a,b);              break;            }            else              sign = 1;       for(i = 0; i < len_a; ++i)           a1[i] = a[i] - '0';       for(j = 0; j < len_b; ++j)           b1[j] = b[j] - '0';       while(i>=0 && j>=0)          {        s[k] = a1[i] - b1[j];//s[0]=0,因为a1[len_a]和b1[len_b]为0        if(s[k] < 0)        {          a1[i-1] -= 1;//借位          s[k]+=10;        }        k++;        i--;        j--;       }        while(i >= 0)        {         s[k] = a1[i];         k++;         i--;        }        if(sign<0)           printf("-");        while(s[k]==0&&k>0)          k--;        if(k == 0)           printf("0");        while(k > 0)        {          printf("%d", s[k]);          k--;        }      return 0;    }


科普:什么是减数什么是被减数?

在减法算式中,减号前面的数是被减数,减号后面的数是减数,等号后面的数是差。

 减数是减法算式中从被减数中扣除的数。被减数就是被减去的那个数。


5.高精度乘法

        #include<string.h> #include<stdio.h>char n[255],m[255];int n1[255],m1[255],s[510];int main(){int i,j, k=0, t, x=0, dig;int lenn, lenm;scanf("%s %s", &n, &m);lenn = strlen(n);lenm = strlen(m);for(i = 0; i < lenn; i++)   n1[i] = n[i] - 48;for(j = 0;j < lenm; j++)   m1[j] = m[j] - 48;for(j = lenm-1; j>=0; j--){t=k;for(i = lenn-1; i >= 0; i--){  s[t]+=n1[i]*m1[j];  t++;    }    ++k;    dig=t;}for(i = 0;i < dig; i++)   while(s[i] >= 10)           {     s[i] -= 10;     ++s[i+1];   }   if(s[dig] != 0)     for(i=dig;i>=0;i--)        printf("%d",s[i]);           else     for(i=dig-1;i>=0;i--)            printf("%d",s[i]);return 0;}




高精度运算涉及到的问题:

1、数据的输入。

2、数据的存储

3、数据的运算:进位和借位。

4、结果的输出:小数点的

高精度运算涉及到的问题:

1、数据的输入。

2、数据的存储。

3、数据的运算:进位和借位。

4、结果的输出:小数点的位置、处理多于的0等。


1 0
原创粉丝点击