基于51单片机的c语言大数计算器

该计算器可计算 大数(理论上无论多少位数都可以),小数,正负数。数据的存储采用字符串形式(比如数字123456,内部字符串为“123456”,符号标志位0,小数点标志为0。若数字为 -12.3456,内部字符串为“123456”,符号标志位1,小数点标志为4。若数字为0.0123,内部字符串为“00123”,符号标志位0,小数点标志为4。),计算方式采用模拟人的计算步骤。上图:

   计算1234567890123+987654321012.3

计算9999999999999-123456789

计算9999999999999*123456789.123

计算9999999999/123456

 

 

基础计算(只进行数字计算):

加法和减法比较简单,考虑到进位和借位就可以了,减法中被减数应大于减数;

加法:

void addx(u8 *s1,u8 *s2,u8 out[]) 
{
	char i,j=0;
	char an1[MAXN]=0;
  char an2[MAXN]=0;
	
	int len1=strlen(s1);
	int len2=strlen(s2);
	
  for(i=len1-1;i>=0;i--) an1[j++]=s1[i]-'0';     //倒写入数组
	j=0;
  for(i=len2-1;i>=0;i--) an2[j++]=s2[i]-'0';    
  j=0;
	for(i=0;i<max(len1,len2)+1;i++)
	{
		an1[i]+=an2[i];
		if(an1[i]>=10)
			{
				an1[i]-=10;                 //大于10则进位
				an1[i+1]++;
		}
		an1[i]+='0';
	}
	i=strlen(an1)-1;   
	while(an1[i]=='0')i--;    //去首位0
	memset(out,0,MAXN);
	for(;i>=0;i--)
	{
		out[j]=an1[i];
		j++;
	}
	
}

减法:

void subx(u8 *s1,u8 *s2,u8 out[]) 
{
	char i,j=0;
	char an1[MAXN]=0;
  char an2[MAXN]=0;

	int len1=strlen(s1);
	int len2=strlen(s2);
	
  for(i=len1-1;i>=0;i--) an1[j++]=s1[i]-'0';    //倒数
	j=0;
  for(i=len2-1;i>=0;i--) an2[j++]=s2[i]-'0';    
  j=0;
	for(i=0;i<max(len1,len2);i++)
	{
    an1[i]-=an2[i];
    if(an1[i]<0)
			{
        an1[i]+=10;
        an1[i+1]--;             //借位
      }
			an1[i]+='0';
		}
	i=strlen(an1)-1;   
	while(an1[i]=='0')i--;    //去首位0
	memset(out,0,MAXN);
	for(;i>=0;i--)
	{
		out[j]=an1[i];
		j++;
	}
}

基础乘法的实现是,将每一位相乘存入数组中,若某一项大于10,者进x/10,保留x%10;

void mulx(u8 *s1,u8 *s2,u8 out[])
{
	u16 c[40]=0;
	char an1[MAXN]=0;
  char an2[MAXN]=0;
	int len1=strlen(s1);
	int len2=strlen(s2);
  int len=len1+len2;                  //两数相乘,最大长度为 len1+len2
	char i,j=0;
	
	for(i=len1-1;i>=0;i--) an1[j++]=s1[i]-'0';     
	j=0;
  for(i=len2-1;i>=0;i--) an2[j++]=s2[i]-'0';    

		for(i=0;i<len1;i++)
	{
		for(j=0;j<len2;j++)
			c[i+j]+=an1[i]*an2[j];   
	}
	for(i=0;i<len;i++)
	{    
			if(c[i]>=10)
			{
				c[i+1]+=c[i]/10;
				c[i]%=10;
			}
			c[i]+='0';
		}  
	j=0;
	i=len-1;   
	if(c[i]=='0')i--;    
	for(;i>=0;i--)
	{
		out[j]=c[i];
		j++;
	}
		
}

除法实现原理:例如123456789/12,首先得到123456789的长度为9,12的长度为2,然后把12后面加(9-2)-1个0,为12000000,  也就是(9-1)=8位长度,然后用123456789循环减12000000一直到差小于12000000 得到循环次数为10,差为3456789(长度7),然后10后面加(9-2)-1个0得到10000000。然后用3456789/12,循环上面方法的的循环次数28,后面加(7-2)-1个0的280000,然后280000+10000000=10280000.依次上面循环直到余数小于12,就可以快速得到商10288065.

void divx(u8 *s1,u8 *s2,u8 out1[])
{
	u8 i,j;
	 char an1[MAXN]=0;
   char an2[MAXN]=0;
	 char an3[MAXN]=0;
	 char an4[MAXN]=0;
		 
	 int len,len1,len2;
   if(com(s1,s2)==0){
        out1[0]='1';
   }
   else if(com(s1,s2)<0){
		    len=strlen(s1);
         out1[0]='0';
   }
   else
	{	
		   i=0;while(s1[i]=='0')i++;j=0;              //去首位0
			 for(;i<strlen(s1);i++)an1[j++]=s1[i];
		   
			 while(com(an1,s2)>=0)
				 {
					  memset(an2,0,MAXN);
					  i=0;while(s2[i]=='0')i++;j=0;             //去首位0
					  for(;i<strlen(s2);i++)an2[j++]=s2[i];
					  len1=strlen(an1)-strlen(an2)-1;            //计算添加0的个数
					  len2=strlen(an2);
						for(i=0;i<len1;i++)an2[len2+i]='0';		 //除数后面添0		
					  while(com(an1,an2)>=0)
						{						 
							subx(an1,an2,an1);
							addx(an3,"1",an3);	              //记录循环个数
						}
						len2=strlen(an3);
						for(i=0;i<len1;i++)an3[len2+i]='0';//循环次数后面添加等除数个数的0				
                        addx(an4,an3,an4);                //做加法 加入an4
						memset(an3,0,MAXN);
         } 

			len=strlen(an4);
			for(i=0;i<len;i++)out1[i]=an4[i];
   }
}

上面仅为基础数运算(整数; 被减数大于减数,被除数大于除数)

 

正负,小数运算。

加法计算比较繁琐,要考虑到 正负数,该加还是减,做减还要考虑到 减数和被减数大小,还有小数点位置,小数点对齐等。

减法就可以直接套用加法 (a - b=a + -b);

乘法直接数字相乘,再考虑到小数点位置,正负号就可以了

除法运算套用乘法(a / b = a * 1/b );应为1/b商会为0,所以用 1e15除b,得到的数把小数点左移15位就可以了

CSDN链接:https://download.csdn.net/download/qq_37788233/12167815

百度云:链接:https://pan.baidu.com/s/1w-Mo2O4ayJRYgmR4iUlZdA 
提取码:do95 

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值