【算法】高精度算法讲解

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
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值