您的位置:首页 > 其它

利用字符实现大数除法运算(纯c实现)

2011-07-08 23:20 459 查看
那年还是语言刚入门的我,不知纠结了几多次,才完成了能支持大数的算术四则运算,现在看起来别是一番滋味哈。
算术四则运算中就数除法的实现最为繁杂,基本思路按照除法笔算的步骤进行,计算商时一位一位的进行,当计算某一位商时则不断地与除数相减,得到的相减次数作为本位商的结果,实现代码如下,代码可读性不高,效率有待优化,英雄莫见笑。


/*
* author:Zhanhang
*
* qq:273711460
* E-mail:zhanxinhang@gmail.com
* HomePage:http://blog.csdn.net/zhanxinhang
*/

#include<stdio.h>
#include<string.h>
#include<malloc.h>
//清多余的零
void clz(char r[]) 
{
  if(r[0]=='-')r++; //使r指针向前移一位;
  int len = strlen(r);
  int i=0,k=0;
  if(len<2)return;		
  if(r[i]=='0')
    {
      for(;r[k]=='0'&&r[k+1]!='.';k++);		
      for(;i<len-k;i++)
	{
	  r[i]=r[i+k];
	}
      r[i]='\0';
    }
}
//清除数可不要的小数点
void clDot(char r[])
{
  int len = strlen(r);
  if(r[len-1]=='.')
    r[len-1]=0;
}
//为除计算之用的减法
void dsub(char a[],char b[])
{
  int i,alen,blen;
  char r,t,jiewei=0;
  char *pb ;	
  alen = strlen(a);
  blen = strlen(b);
  pb = (char *)calloc(alen,sizeof(char));
  //使pb与a位数对齐//
  memset(pb,'0',alen);
  t = alen;
  for(i=blen-1;i>=0;i--)
    pb[--t]=b[i];

  for(i=alen-1;i>=0;i--) //相减运算
    {
      t = a[i]-jiewei;
      if(t<pb[i]) jiewei=1;
      else jiewei = 0;
      r = (t+jiewei*10)-pb[i];		
      a[i] = r+'0';
    }
  a[alen]='\0';
  clz(a);
  free(pb);
}
//比较两数的大小
int cmp(const char a[],const char b[])
{
  int alen = strlen(a);
  int blen = strlen(b);
  if(alen>blen)
    return 1;
  else if(alen == blen)
    {
      if(strcmp(a,b)>0)
	return 1;
      if(strcmp(a,b)==0)
	return 0;
    }
  else return -1;
}
//除法计算
void div(const char a[],const char b[],char result[])
{		
  bool isNegative = false;
  char *op1,*pa,*pb,*pr;
  int up,alen,blen,adotp,bdotp,i,k,dotp,t,t1,j,quo_size;
  /////////////判定符号///////////////
  //如果为异号
  if((a[0] == '-'||b[0] == '-')&&a[0] != b[0]) 
    result[0] = '-',isNegative = true;

  //去除负号
  if(a[0] == '-')a++;
  if(b[0] == '-')b++;
  ///////////////////////////////////

  alen = strlen(a)-1; //减去一位小数点
  blen = strlen(b)-1;

  ///////获取被除数小数点移位后的位置//////////
  adotp = strchr(a,'.')-a;
  bdotp = strchr(b,'.')-b;

  //计算商小数点位置
  dotp = adotp+blen-bdotp;  
  if(isNegative)dotp++;
 
  //////////准备数据/////////////
  op1 = (char *)calloc(alen+blen+1,sizeof(char)); 
  pa = (char *)calloc(alen+blen+1,sizeof(char));
  pb = (char *)calloc(blen+1,sizeof(char));
  pr = (char *)calloc(alen+blen+1,sizeof(char));

  for(i = 0,t=0; i<=alen; i++)
    {
      if(a[i]!='.')
	pa[t++] = a[i]; 
    }
  for(;t<dotp-1;t++) 
    {
      pa[t] = '0';
    }
  for(;t<blen;t++)
    {
      pa[t] = '0';
    }

  pa[t] = '\0';
  for(i = 0,t=0; i<=blen; i++)
    {
      if(b[i]!='.')
	pb[t++] = b[i]; 
    }
  pb[t] = '\0';
  clz(pa);
  clz(pb);
  ////////取得被除数的高位数op1,且op1大于被除数b//////////
  strncpy(op1,pa,strlen(pb));
  if(strcmp(op1,pb)<0)
    {
      strncpy(op1,pa,strlen(pb)+1);
    }

  /////计算//////
  j = k = strlen(op1);
  t1=0;
  quo_size = strlen(pa)+1-k; //获取商的长度
  
  while(t1<quo_size)
    {			
      up = 0;
      t = cmp(op1,pb);
      while(t>=0)
	{
	  dsub(op1,pb);				
	  t = cmp(op1,pb);
	  up++;
	}
      pr[t1++] = up+'0';
	op1[strlen(op1)]=pa[j++];			
	clz(op1);
    }
  quo_size+=50;//加50精度
  while(t1<quo_size&&(cmp(op1,(char *)"0")>0))
    {
      up = 0;
      op1[strlen(op1)]='0';
      t = cmp(op1,pb);						
      while(t>=0)
	{
	  dsub(op1,pb);				
	  t = cmp(op1,pb);				
	  up++;
	}
      pr[t1++] = up+'0';					
    }
  //////////////////////////////

  if(isNegative)t=1;
  else t=0;
  for(i=0;i<=t1;i++)//复制结果并给商加上小数点
    {
      if(t==dotp) result[t++] = '.';
      result[t++]=pr[i];
    }	

  clz(result);
  clDot(result);
  free(op1);
  free(pa);
  free(pb);
}
main()
{
  char result[500]={0};

  div("-9999.","3.",result);
  printf("%s\n",result);

  div("10000000000000000000000000.","5.",result);
  printf("%s\n",result);

  div("12345678900.","12345678900.",result);
  printf("%s\n",result);

  div("1.","3.",result);
  printf("%s\n",result);

  div("-444.","-2.",result);
  printf("%s\n",result);

  div("6660.","-3330.",result);
  printf("%s\n",result);

  div("1.","3333333333333333333333.",result); //bug
  printf("%s\n",result);
}

结果:(每一行对应于main中的每一次调用div所得到的结果)



======= welcome to my HomePage(http://blog.csdn.net/zhanxinhang) to have a communication =======
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: