c++大数加减乘除(高精度运算的加法、减法、乘法、除法)

随便瞎说系列

忘记是什么时候老师教的大数加减乘除了,也很久没有碰过c或者c++了,在刷面试题的时候发现很多编程题目一开始都会涉及到大数,所以现在就先整理出来进行再一次梳,简单粗暴,代码奉上。

为什么要用到高精度

首先普及一下c的数据类型中的整数类型,基本要了解的如下:

类型 存储大小 范围
char 1字节 -128 到 127 或 0 到 255
unsigned char 1字节 0 到 255
signed char 1 字节 -128 到 127
int 4 字节 -2,147,483,648 到 2,147,483,647
unsigned int 4 字节 0 到 4,294,967,295
short 2 字节 -32,768 到 32,767
unsigned short 2 字节 0 到 65,535
long 4 字节 -2,147,483,648 到 2,147,483,647
unsigned long 4 字节 0 到 4,294,967,295

当我们进行整数运算时,计算机只能对范围为-2,147,483,648 到 2,147,483,647且结果也在int范围内的整数进行运算,为了防止数据溢出导致的计算机运算错误,我们使用某种办法代替计算机的运算。

高精度运算之减法

#include
#include
#define MAX 100001
using namespace std;
int subtraction(char a[],char b[],int c[]){
	int len1,len2,i,j,k;
	k=0;
	len1=strlen(a)-1;
	len2=strlen(b)-1;
	for(i=len1,j=len2;i>=0;i--,j--)
	{
		if(j>=0)//做减法 
		{
			if(a[i]=0;i--)
		if(c[i]!=0)
			break;
	return i;
}
int main(void)
{
	char a[MAX],b[MAX];
	int c[MAX];
	int len;
	while(scanf("%s%s",a,b)!=EOF)
	{
		len=subtraction(a,b,c);
		//清0准备输出 
		if(len>=0)
			for(;len>=0;len--)
				printf("%d",c[len]);
		else
			printf("0");
		printf("\n");
	}
	return 0;
}

测试数据
999999999999999999999999999999999999999999999999 22222222222222222222222222222222
结果
999999999999999977777777777777777777777777777777

高精度运算之加法

#include
#include
#define MAX 100001
using namespace std;
int addition(char a[],char b[],int c[]){

	
	int len1,len2,i,j,k,sign;
	sign=0;k=0;
	len1=strlen(a)-1;
	len2=strlen(b)-1;
	 
	for(i=len1,j=len2;i>=0||j>=0;i--,j--)
	{ 
		if(j>=0&&i>=0)
		{
			if(a[i]+b[j]+sign>'0'+'0'+9)
			{
				c[k]=a[i]+b[j]-'0'-'0'-10+sign;
				sign=1;
			}
			else
			{
				c[k]=a[i]+b[j]-'0'-'0'+sign;
				sign=0;
			}
		}
		else if(i>=0&&j<0)
		{
			if(a[i]+sign>'9') 
			{
				c[k]=0;
			}
			else 
			{
				c[k]=a[i]-'0'+sign;
				sign=0;
			}
		}
				
		else
		{
			if(b[j]>='9'&&sign==1) c[k]=0;
			else 
			{
				c[k]=b[j]-'0';
				sign=0;
			}
		}				
		k++;
	}
	if(sign==1)
	{
		c[k]=1;
		k++;
	}
	for(i=k-1;i>=0;i--)
		if(c[i]!=0)
			break;
	return i;

}
int main(void)
{
	char a[MAX],b[MAX];
	int c[MAX];
	int len;
	while(scanf("%s%s",a,b)!=EOF)
	{
		len=addition(a,b,c);
		//清0准备输出 
		if(len>=0)
			for(;len>=0;len--)
				printf("%d",c[len]);
		else
			printf("0");
		printf("\n");
	}
	return 0;
}

测试数据
444444444444444444444444444 655555555555555555555555555
结果
1099999999999999999999999999

高精度运算之乘法

#include 
#include 
using namespace std;
typedef string BigInt;



BigInt ClearZero(BigInt x) //清除数前面的0
{
	int i;
	for (i = 0; i < x.length(); i++)
		if (x[i] != '0')
			break;

	if (i == x.length())
		return "0";
	else
		return x.erase(0, i);
}

BigInt addition(BigInt a, BigInt b)
{
	int l1 = a.length();
	int l2 = b.length();
	while (l1 < l2) //将两个数的长度对齐,在两个数前面补0
	{
		a = '0' + a;
		l1++;
	}
	while (l1 > l2)
	{
		b = '0' + b;
		l2++;
	}
	a='0'+a;
	b='0'+b;
//	cout<= 0; i--)
	{
		if (( a[i] + b[i] )>( '0' + 9 +'0' ))
		{
			a[i] -= 10;
			a[i-1]++;
		}
		a[i]=a[i]+b[i] - '0';
//		cout << a[i] << endl;
	}
	return ClearZero(a);
}
BigInt multiplication(BigInt a,BigInt b)
{
	BigInt c="0",d;
	int i,j;
	
	for(j=b.length()-1 ;j>=0;j--)
	{
		d=a;
		for(i=2;i<=(b[j]-'0');i++)
		  d=addition(d,a);
		if((b[j]-'0')>0)c=addition(c,d);
		a=a+'0';
	}
	return c;
}
int main()
{
	BigInt a, b;
	while (cin>>a>>b)
	{
          cout<

测试数据
123456789 123456789
运算结果
15241578750190521

高精度运算之除法

#include
#include
#define MAX 100001
using namespace std;
int SubStract(int *p1, int len1, int *p2, int len2)
{
    int i;
    if(len1 < len2)
        return -1;
    if(len1 == len2 )
    {                        // 判断p1 > p2
        for(i = len1-1; i >= 0; i--)
        {
            if(p1[i] > p2[i])   // 若大,则满足条件,可做减法
                break;
            else if(p1[i] < p2[i]) // 否则返回-1
                return -1;
        }
    }
    for(i = 0; i <= len1-1; i++)  // 从低位开始做减法
    {
        p1[i] -= p2[i];         // 相减
        if(p1[i] < 0)           // 若是否需要借位
        {   // 借位
            p1[i] += 10;
            p1[i+1]--;
        }
    }
    for(i = len1-1; i >= 0; i--)  // 查找结果的最高位
    {
        if( p1[i] )             //最高位第一个不为0
            return (i+1);       //得到位数并返回
    }
    return 0;                   //两数相等的时候返回0
}
 
 
int Division(char num1[], char num2[], int sum[])
{
    int k, i, j;
    int len1, len2, len=0;     //大数位数
    int dValue;                //两大数相差位数
    int nTemp;                 //Subtract函数返回值
    int num_a[MAX] = {0};      //被除数
    int num_b[MAX] = {0};      //除数
    int num_c[MAX] = {0};      //商
 
    len1 = strlen(num1);       //获得大数的位数
    len2 = strlen(num2);
 
    //将数字字符转换成整型数,且翻转保存在整型数组中
    for( j = 0, i = len1-1; i >= 0; j++, i-- )
        num_a[j] = num1[i] - '0';
    for( j = 0, i = len2-1; i >= 0; j++, i-- )
        num_b[j] = num2[i] - '0';
    
 
    if( len1 < len2 )          //如果被除数小于除数,直接返回-1,表示结果为0
    {
        return -1;
    }
    dValue = len1 - len2;      //相差位数
    for (i = len1-1; i >= 0; i--)    //将除数扩大,使得除数和被除数位数相等
    {
        if (i >= dValue)
            num_b[i] = num_b[i-dValue];
        else                         //低位置0
            num_b[i] = 0;
    }
    len2 = len1;
    for(j = 0; j <= dValue; j++ )    //重复调用,同时记录减成功的次数,即为商
    {
        while((nTemp = SubStract(num_a, len1, num_b+j, len2-j)) >= 0)
        {
            len1 = nTemp;            //结果长度
            num_c[dValue-j]++;       //每成功减一次,将商的相应位加1
        }
    }
    // 计算商的位数,并将商放在sum字符数组中
    for(i = MAX-1; num_c[i] == 0 && i >= 0; i-- );  //跳过高位0,获取商的位数
    if(i >= 0)
        len = i + 1; // 保存位数
    for(j = 0; i >= 0; i--, j++)     // 将结果复制到sum数组中
        sum[j] = num_c[i];
	
    return len;      // 返回商的位数
}
int main(void)
{
	char a[MAX],b[MAX];
	int c[MAX];
	int len;
	while(scanf("%s%s",a,b)!=EOF)
	{
		len=Division(a,b,c);
		//清0准备输出 
		if(len>=0)
			for(int i = 0; i < len; i++ )
				printf("%d",c[i]);
		else
			printf("0");
		printf("\n");
	}
	return 0;
}

测试数据
15241578750190521 123456789
运算结果
123456789

到现在为止就要结束啦,希望以后还能坚持一直写下去

你可能感兴趣的:(c,or,c++)