码迷,mamicode.com
首页 > 其他好文 > 详细

大数运算-(加、减、乘)

时间:2016-08-05 12:01:47      阅读:359      评论:0      收藏:0      [点我收藏+]

标签:

       大数其实和一般数字的区别在于大数的存储。一般数字可以用已有类型表示,如int。但是大数动不动100位,这样的话大数用什么存储已然是个问题。我仔细查找了下,大多数要么用char数组,要么用string表示。有大数了,那么它的计算怎么写?和普通四则运算一致。

1.加法

       以十进制计算符合我们的日常习惯。同时暂且不考虑正负数的问题。那么就以两个正的大数相加为例,类比普通十进制的加法,就是从个位依次相加,和超过10就进位。看起来也不难,无非就是个位相加,超十进一。那么问题的重点就在于我们从低位相加没问题,什么时候停止相加,结果保存在哪,进位怎么处理?

       当然以两个数的最小长度为相加终止条件,进位用一个变量表示即可。下面是参考代码:

       注意数的低位高位保存的顺序自己要约定好。

       

//0的ASCII码是48
void Add(char a[],char b[],char d[])
{
   char c[10001];
   int lena=strlen(a),lenb=strlen(b);
   int i,j,len;
   len=max(lena,lenb);
   len++;
   c[0]='\0';
   for(i=1;i<=len;i++)c[i]='0';
   for(i=1;i<=lena;i++)c[i]+=a[lena-i]-48;
   for(i=1;i<=lenb;i++)c[i]+=b[lenb-i]-48;
   for(i=0;i<=len;i++)
   if(c[i]>57)
   {
     c[i]-=10;
     c[i+1]++;
    }

    for(i=len;i>1;i--)
      if(c[i]==48)len--;
      else break;
    for(i=0;i<=len;i++)
        d[i]=c[len-i];
 }
     

       那么符号问题怎么解决呢?联系我们平常的运算,如果两个数符号相同,那么忽略符号进行两数相加,结果的符号相同。两数符号不同时,可以等效于做减法。

2.减法

           同样的类比,我们是从个位相减,不够减向高位借一当十。这里我多说一句,看见很多人搞混。被减数是第一个数,键鼠是第二个数。是以“-”号运算符分开的。我们通常选取两个数中较长的数作为被减数。从低位向高位按位相减。

<span style="font-size:18px;">//假设d2的长度大于d1
void dec(char *d1, char *d2, char *out)
{
    int len_min = strlen(d1);
    int len_max = strlen(d2);
    int last_j = 0;     //最关键的错位
    while(len_min > 0)
    {
        int dd1 = d1[len_min - 1] - '0';
        int dd2 = d2[len_max - 1] - '0';
        if (last_j) dd2 = dd2 - 1;
        last_j = dd2 >= dd1 ? 0 : 1;
        dd2 = dd2 >= dd1 ? dd2 : dd2 + 10;
        out[len_max] = (dd2 - dd1) + '0';
        len_max -- ;
        len_min -- ;
    }
    while(len_max > 0)
    {
        int dd2 = (d2[len_max -1] - '0');
        if (last_j) dd2 = dd2 - 1;
        last_j = dd2 >= 0 ? 0 : 1;
        dd2 = dd2 >= 0 ? dd2 : dd2 + 10;
        out[len_max] = dd2 + '0';
        len_max --;
    } 
    if (last_j)
          out[0] ='1';
    else
          out[0] ='0';
}</span>

       最后是设置标志位,负数为1,正数为0。

3.乘法

      乘法是这样的,如12*21。个位乘个位,个位乘十位相加求和。如果将大数从个位开始标注索引0,1,2,3....n。只要两数的索引和相同就相加到第i+j位,和超过10则进位。如下:

       

void Mul(char a[],char b[],char c[])//大数乘法
{
    int i,j;
    int alen=strlen(a),blen=strlen(b);
	int Len=max(alen,blen);
    for(i=0; i<Len; i++) c[i]=0;
    for(i=0; i<alen; i++)
        for(j=0; j<blen; j++) //处理进位
        {
            c[i+j]+=a[i]*b[j];
            if(c[i+j]>=10)
            {
                c[i+j+1]+=c[i+j]/10;
                c[i+j]%=10;
            }
        }
}
      总之,我写的比较简单,但思想是这样的。

       

大数运算-(加、减、乘)

标签:

原文地址:http://blog.csdn.net/yutianxin123/article/details/52126231

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!