大数运算(加减乘除,阶乘,取余)

 

目录

一、概述

什么是大数

怎么进行运算

二、具体实现

大数加法

大数减法

大数乘法

大数除法,大数取余

三、应用

 

一、概述

 

  • 什么是大数

    我们常见的数据其数据范围大都在int(-2^31 —2^31-1)或者long long( -2^62 — 2^62-1)之内,但在有些特殊情况下,我们会遇到超过这个范围的数据,这些数据就称为题目中提到的大数。

     当然,大数不只是大整数,对于数位较多的小数,如123456789.123456789有时也适用于大数运算。

 

  • 怎么进行运算

      大数运算主要包括加减乘除,阶乘,取余等运算,对于大数,我们一般用字符数组存储,其中每个数组元素都对应一个数位。而实现这些运算的大致思路都是模拟竖式计算的过程,即通过模拟进位,借位,取余的操作完成计算。

 

二、具体实现

 

  • 大数加法

大数加法可以从个位依次相加,和大于十就进一,否则不进位,最后对最高位进行判断,大于十就进位,否则不操作。

#include<bits/stdc++.h>
using namespace std;
int main()
{   int a[1000],b[1000],c[1000];
    int k,j,i,n,m,up=0;
    string s;
    cin>>s; n=s.length(); k=0;  //字符串转化
    for( i=n-1;i>=0;i--)
      {  a[k]=s[i]-'0';
         k++;
      }
    cin>>s; m=s.length(); k=0; //字符串转化
    for( i=m-1;i>=0;i--)
      { b[k]=s[i]-'0';
        k++;
      }
    for( i=0;i<max(m,n);i++)    
    {  c[i]=(a[i]+b[i]+up)%10;  //相同位数上两数及进位相加
       up=(a[i]+b[i]+up)/10;    //逢十进一
    }
    i--;
    if(c[i]>=10)
      { c[i+1]=c[i]/10;c[i]=c[i]%10;i++;} //判断最高位是否大于十
    for( j=i;j>=0;j--)  //逆序输出
      cout<<c[j];
}

 

  • 大数减法

大数减法与加法相似,不同的是要先判断减数与被减数的大小,减数大直接进行减法操作,否则用被减数减去减数,再加负号。减法操作就是从个位依次相减,不够减就借一,最后一位直接相减。

 

#include<bits/stdc++.h>
using namespace std;
int a[1000],b[1000],c[1000];
int main()
{   int k,j,i,n,m,kk;
    void sub(int a[],int b[],int p);
    string s,ss;
    cin>>s;  n=s.length();  k=0;
    cin>>ss; m=ss.length(); kk=0;
      for( i=n-1;i>=0;i--)
        {  a[k]=s[i]-'0';
           k++;
        }
      for( i=m-1;i>=0;i--)
         { b[kk]=ss[i]-'0';
           kk++;
         }
    if(n>m) sub(a,b,n);            //被减数数位长,直接减
    else if(n<m) {cout<<"-";sub(b,a,m);} //被减数数位长,减数减去被减数,前加负号
    else
    { for(i=0;i<n;i++)            //被减数和减数数位相同,判断大小
       { if(a[i]==b[i]) continue;
         else if(a[i]<b[i]) {cout<<"-";sub(b,a,n);break;}
         else {sub(a,b,n);break;}
       }
    }
}
void sub(int a[],int b[],int p)   //a-b函数
{   int i,j;
    for( i=0;i<p;i++)
     {  if(a[i]-b[i]>0) c[i]=(a[i]-b[i]);
        else {a[i+1]--; c[i]=(a[i]+10-b[i]);}
     }
    c[i]=(a[i]-b[i]);
    for( j=i-1;j>=0;j--)
      cout<<c[j];
}

 

  • 大数乘法

大数乘法即用第一个数的第i位,依次乘上第二个数的第k位,加到结果数组中。之后各个数组元素进行取余,进位。最后去除前导零,倒序输出。

 

#include<stdio.h>
#include<string.h>
#define MAX 100
char a[MAX],b[MAX];//用字符串进行数字的输入
int x[MAX+10],y[MAX+10],z[MAX*2+10];//积的位数最多是因数位数的两倍
int main()
{
	int len1,len2,i,j;
	while(~scanf("%s %s",a,b))
	{
		len1=strlen(a);
		len2=strlen(b);
		for(j=0,i=len1-1;i>=0;i--)//将字符串中字符转化为数字,并倒序储存
			x[j++]=a[i]-'0';
		for(j=0,i=len2-1;i>=0;i--)
			y[j++]=b[i]-'0';
		for(i=0;i<len1;i++)//将因数各个位上的数字与另一个各个位上的数字相乘
		{
			for(j=0;j<len2;j++)
				z[i+j]=z[i+j]+x[i]*y[j];//先乘起来,后面统一进行进位
		}
		for(i=0;i<MAX*2;i++)//进行进位
		{
			if(z[i]>=10)  //若>=10
			{
				z[i+1]=z[i+1]+z[i]/10;  //将十位上数字进位
				z[i]=z[i]%10;  //将个位上的数字留下
			}
		}
		for(i=MAX*2;i>0;i--)  //删除0的前缀
		{
			if(z[i]==0)
				continue;
			else
				break;
		}
		for(;i>=0;i--)  //倒序输出
			printf("%d",z[i]);
		printf("\n");
	}
	return 0;
}

 

  • 大数除法,大数取余

       有两个大整数a和b,当a=b时,a/b==1,余数是0,  当a>b时,a/b>=1,余数需要通过计算求得,当a<b时,a/b=0,余数就是a。
        而我们经常需要求的便是当a>b,这种情况我们基本的思想就是反复做减法,从被除数里最多能减去多少个除数即是商,进而求出余数。
        另外,注意:我这里写的是有关大数除以大数的除法,同样适用于大数除以int类型范围的数,当然,也可以另写关于大数除以int的数。
这里写的全部是大整数,不包括小数。

#include<stdio.h>
#include<string.h>
char a[100],b[100];//用两个字符串用来输入两个大数 
int x[100],y[100],z[100],m[100];//被除数  除数  商  余数 
int digit;//大数的位数 
void sub(int x[],int y[],int len1,int len2)//大数减法 
{
	int i;
	for(i=0;i<len1;i++)
	{
		if(x[i]<y[i])   
		{
			x[i]=x[i]+10-y[i];
			x[i+1]--;
		}
		else
			x[i]=x[i]-y[i];
	}
	for(i=len1-1;i>=0;i--)//判断减法结束之后,被除数的位数 
	{
		if(x[i])
		{ 
			digit=i+1;
			break;		   
		} 
	}
}
int judge(int x[],int y[],int len1,int len2)
{
	int i;
	if(len1<len2)
		return -1;
	if(len1==len2)//若两个数位数相等 
	{
		for(i=len1-1;i>=0;i--)
		{
			if(x[i]==y[i])//对应位的数相等 
				continue;
			if(x[i]>y[i])//被除数 大于 除数,返回值为1 
				return 1;
			if(x[i]<y[i])//被除数 小于 除数,返回值为-1 
				return -1;
		}
		return 0;//被除数 等于 除数,返回值为0 
	}	
}
int main()
{
	int i,j=0,k=0,temp;
	int len1,len2,len;//len两个大数位数的差值   
	while(~scanf("%s %s",a,b))
	{
		len1=strlen(a);//被除数位数
		len2=strlen(b);//除数位数
		for(i=len1-1,j=0;i>=0;i--)//将字符串中各个元素倒序储存在数组中 
			x[j++]=a[i]-'0';
		for(i=len2-1,k=0;i>=0;i--)
			y[k++]=b[i]-'0';		    
		if(len1<len2)//当被除数位数 小于 除数位数时 
		{
			printf("商是:0\n");
			printf("余数是:");
			puts(a); 
		}
		else //当被除数位数 大于或者 除数位数时
		{
			len=len1-len2;//两个大数位数的差值
			for(i=len1-1;i>=0;i--)//将除数后补零,使得两个大数位数相同。 
			{
				if(i>=len)
					y[i]=y[i-len];
				else
					y[i]=0;
			}
			len2=len1;//将两个大数数位相同 		
			digit=len1;	//将原被除数位数赋值给digit 
			for(j=0;j<=len;j++)
            {
				z[len-j]=0;
				while(((temp=judge(x,y,len1,len2))>=0)&&digit>=k)//判断两个数之间的关系及位数与除数原位数的关系 
				{	
					sub(x,y,len1,len2);	//大数减法函数			    
					z[len-j]++;//储存商的每一位
					len1=digit;//重新修改被除数的长度
					if(len1<len2&&y[len2-1]==0)		
						len2=len1;//将len1长度赋给len2;						
				}
				if(temp<0)//若被除数 小于 除数,除数减小一位。 
				{
					for(i=1;i<len2;i++)
						y[i-1]=y[i];
					y[i-1]=0;
					if(len1<len2) 
						len2--;			        				        
				}
			}
			printf("商是:");
			for(i=len;i>0;i--)//去掉前缀0 
			{
				if(z[i])
					break;
			}
			for(;i>=0;i--)
				printf("%d",z[i]);
			printf("\n");
			printf("余数是:");
			for(i=len1;i>0;i--)
			{
				if(x[i])
					break;
			}
			for(;i>=0;i--)
				printf("%d",x[i]);
			printf("\n");
		}
	}
	return 0;
}

 

 

三、应用

      与其说大数运算是种算法,倒不如说他是一种工具,熟练掌握了这个工具,那么不论他与其他算法怎么结合,都不会难倒你。

       下面就分享一个大数运算的经典题,供各位小试牛刀:

有一个8*8共64格的棋盘,要求第一个格放1粒米,第二个格放2粒米,第三个放4粒,依次加倍,问放满棋盘共有多少粒米。

很显然,这是个很大的数,用long型也无法存放。所以只能通过模拟加法和乘法来达到计算的目的。
 

#include <iostream>
using namespace std;
void multi2(short a[])  //模拟乘2运算
{   short carry = 0;    //进位置零
   for(short i=999;i>=0;i--)
    {  short tmp =a[i]*2;
         a[i]=tmp%10+carry;  //当前位结果
      carry=tmp/10;       //进位       
    }
    return;
} 

void plus(short sum[],short add[]) //模拟加运算
{     short carry = 0;
    for(short i=999;i>=0;i--)
        { short tmp = sum[i]+add[i];
          sum[i]=tmp%10 + carry;
       carry=tmp/10;       
       }
      return;           
}

int main()
{   short sum[1000]={0};
   short add[1000]={0};
   add[999]=1;
   for(short i=0;i<64;i++)
    {  plus(sum,add);
         multi2(add);
    }    
    short k = 0; 
    for(short j=0;j<1000;j++)
     if(sum[j]!=0) { k=j;break;}
    cout<<"result:"<<endl;
    for(short i=k;i<1000;i++)
    cout<<sum[i];
   cout<<endl;
   getchar();
   return 0;
}

 

 

 

 

 

 

 

 

  • 6
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
好的,以下是一个简单的Java程序,演示了基本的数学运算、函数和阶乘: ```java import java.util.Scanner; public class BasicMathOperations { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.print("请输入一个数字:"); double num1 = scanner.nextDouble(); System.out.print("请输入另一个数字:"); double num2 = scanner.nextDouble(); double sum = num1 + num2; double difference = num1 - num2; double product = num1 * num2; double quotient = num1 / num2; System.out.println("和为:" + sum); System.out.println("差为:" + difference); System.out.println("积为:" + product); System.out.println("商为:" + quotient); System.out.println("请输入一个角度(0-360度):"); double angle = scanner.nextDouble(); double radian = Math.toRadians(angle); double sine = Math.sin(radian); double cosine = Math.cos(radian); double tangent = Math.tan(radian); System.out.println("正弦值为:" + sine); System.out.println("余弦值为:" + cosine); System.out.println("正切值为:" + tangent); System.out.print("请输入一个整数:"); int num = scanner.nextInt(); int factorial = 1; for (int i = 1; i <= num; i++) { factorial *= i; } System.out.println(num + "的阶乘为:" + factorial); } } ``` 这个程序通过使用`Scanner`类从用户处获取输入,然后执行基本的数学运算和函数计算。其中,`Math`类提供了许多常见的数学函数,如`sine`、`cosine`和`tangent`等。阶乘的计算使用了一个简单的`for`循环。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

亦木不emo

打赏一个吧亲

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值