大数加减乘法

大数存储:由于x的位数最大为400位,我们不能用现有的int,longlong,double等数据类型进行存储。一般存储大数的方法是用一个字符串来表示。

方法:模拟小学生算术。

在这里我们先讨论全为正整数的情况哈。

大数加法

 123

+ 23

  146

对应位数相加,最后再进位,满十进一,为了方便计算,我们采用低位在前,高位在后的逆序存储相加后的结果。(两个数相加结果最大只会比较大的多一位)

123456+5677

654321
7765  
131210821

C语言实现

#include<stdio.h>
#include<string.h> 
const int maxn=1000+7;
using namespace std;
void plus(int a[],int b[],int len) 
{
	//给每一位作加法,满十进一 
	for(int i=0;i<len;i++) 
	{
		a[i]+=b[i];
		if(a[i]>=10) 
		{
			a[i]-=10;
			a[i+1]+=1;
		}
	}
	//去掉前缀0 
	int flag=0;
	for(int i=len;i>=0;i--)
	{ 
		if(a[i]!=0)
		{
			flag=1;
			for(i=i;i>=0;i--)
			printf("%d",a[i]);
			break;
		}
		
	}
	if(flag==0)
	printf("0");
	printf("\n");
	
}
int main()
{
	char str2[maxn],str1[maxn];
	int a[maxn],b[maxn];
	int n,len1,len2,len;
	scanf("%d",&n);
	getchar();
	while(n--)
	{ 
		memset(a,0,sizeof(a));
		memset(b,0,sizeof(b));
		scanf("%s%s",str1,str2);
		len1=strlen(str1);
		len2=strlen(str2);
		if(len1>len2)
		 len=len1;
		else
		 len=len2;
		for(int i=0;i<len1;i++)	//将字符编码的数字转换为对应的数 
		{
			a[i]=str1[len1-i-1]-'0';
		}
		for(int i=0;i<len2;i++)
		{
			b[i]=str2[len2-i-1]-'0';
		 } 
		plus(a,b,len);
	
	}
	return 0;
}

Java实现

import java.math.BigInteger;
import java.util.Scanner;
 
public class 大数加法 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n =sc.nextInt();
		for(int i=1;i<=n;i++){
			BigInteger a = sc.nextBigInteger();
			BigInteger b = sc.nextBigInteger();
			System.out.println(a+" + "+b+" = "+a.add(b));
			
		}
	}
}

大数减法

和大数加法原理类似,对应位数相减,最后小于0的加10,它的后一位-1;

654321-2042

123456
2402  
-1-23256

 

该规则遵守大数减小数,因此先比较两个字符串的长度,长度长的数字大,长度相等,比较高位,如果相等依次类推。

我们可以把大数-小数直接进行上述的规则计算,小数-大数,可以交换他们的位置,变成为大数减小数,并在最前面加上负号。

c语言实现

#include<stdio.h>
#include<string.h>
const int maxn=1000+7;
using namespace std;
void sub(int a[],int b[],int len)
{
	for(int i=0;i<len;i++) 
	{
		a[i]-=b[i];
		if(a[i]<0) 
		{
			a[i]+=10;
			a[i+1]-=1;
		}
	}
	int flag=0;//删除前缀0 
	for(int i=len;i>=0;i--)
	{ 
		if(a[i]!=0)
		{
			flag=1;
			for(i=i;i>=0;i--)
			printf("%d",a[i]);
			break;
		}	
	}
	if(flag==0)//结果为0时 
	printf("0");
	printf("\n");
	
}
int main()
{
	char str1[maxn],str2[maxn];
	int len1,len2,a[maxn],b[maxn];
	while(~scanf("%s%s",str1,str2))
	{
		len1=strlen(str1);
		len2=strlen(str2);
		memset(a,0,sizeof(a));
		memset(b,0,sizeof(b));
	    for(int i=0;i<len1;i++)
		{
			a[i]=str1[len1-i-1]-'0';
		}
		for(int i=0;i<len2;i++)
		{
			b[i]=str2[len2-i-1]-'0';
		 } 
		 if(len1>len2) //若减数长度>被减数,按照规则直接减     
           sub(a,b,len1);  
         else if(len1<len2)//若减数长度<被减数,用被减数-减数   
         {  
            printf("-");  
            sub(b,a,len2);  
         }   
          else  //若减数长度==被减数长度,判断两个数每位的大小   
         {  
            for(int i=len1-1;i>=0;i--)//判断每一位两个数的大小  
            {  
                if(a[i]==b[i])  
                    continue;  
                if(a[i]>b[i])//即减数大   
                {  
                    sub(a,b,len1);  
                    break;  
                }      
                if(a[i]<b[i])//即被减数大   
                {  
                    printf("-");  
                    sub(b,a,len1);  
                    break;   
                }      
            } 
		}
	}
return 0;
}

Java实现

import java.math.BigInteger;
import java.util.Scanner;
 
public class 大数减法 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n =sc.nextInt();
		for(int i=1;i<=n;i++){
			BigInteger a = sc.nextBigInteger();
			BigInteger b = sc.nextBigInteger();	
			System.out.println(a+" - "+b+" = "+a.subtract(b));
			
		}
	}
}

我写的这个只能算a>b的情况。

大数乘法

模拟竖式计算

num1d的第i位与num2的第j位相乘,把结果放在结果的第i+j位上,每趟都进行相乘,每趟算出累加后的和,然后对这些相加结果进行进位。(积的位数最多是最大因数位数的两倍)

232*1234

 4321  
28642  
3 12+69+46+23 
2  8+9+46+6+24+32
 818211472

c语言实现

#include<stdio.h>
#include<string.h> 
const int maxn=1000+7;
using namespace std;
void multiply(int a[],int b[],int result[],int len1,int len2,int len) 
{
	int j;
	for(int i=0;i<len1;i++)
	{
		for(j=0;j<len2;j++)
		{
		result[i+j]+=a[i]*b[j];
		result[i+j+1]+=result[i+j]/10;
		result[i+j]=result[i+j]%10;
       }
	}
      int flag=0;
	for(int i=2*len;i>=0;i--)
	{ 
		if(result[i]!=0)
		{
			flag=1;
			for(i=i;i>=0;i--)
			printf("%d",result[i]);
			break;
		}
		
	}
	if(flag==0)
	printf("0");
	printf("\n");
	
}
int main()
{
	char str2[maxn],str1[maxn];
	int a[maxn],b[maxn],result[maxn*2];
	int n,len1,len2,len;
	while(~scanf("%s%s",str1,str2))
	{ 
		memset(a,0,sizeof(a));
		memset(b,0,sizeof(b));
		memset(result,0,sizeof(result));
		
		len1=strlen(str1);
		len2=strlen(str2);
		if(len1>len2)
		 len=len1;
		else
		 len=len2;
		for(int i=0;i<len1;i++)	//将字符编码的数字转换为对应的数 
		{
			a[i]=str1[len1-i-1]-'0';
		}
		for(int i=0;i<len2;i++)
		{
			b[i]=str2[len2-i-1]-'0';
		 } 
		multiply(a,b,result,len1,len2,len);
	
	}
	return 0;
}

java实现

import java.math.BigInteger;
import java.util.Scanner;
 
public class 大数乘法 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n =sc.nextInt();
		for(int i=1;i<=n;i++){
			BigInteger a = sc.nextBigInteger();
			BigInteger b = sc.nextBigInteger();	
			System.out.println(a+" * "+b+" = "+a.multiply(b));
			
		}
	}
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值