编程学习笔记3--大整数的运算

来源:互联网 发布:js实现动态时钟 编辑:程序博客网 时间:2024/04/30 20:14

本来是打算写四种大整数的计算的,但是除法没有成功,因为当初只看到了题目里面求加法的计算,突发奇想准备把四种都写处出来,但是一开始的时候没有考虑到除法会用到减法,函数运行一直出错,以后思考了,先放过去了大笑


题目当时要求计算长的整数的加法,数据为比较多的,其实无非就是不能直接用一个变量存储的整数的运算。

感悟:奋斗大数据的处理,感觉就是考察对数组的运用,加法和减法的处理是比较简单的,但是乘法和除法的处理就需要很强的技巧了。除法的自己还没有想好哭


#include<stdio.h>#include<string.h>/**计算数字长度少于200内的乘法*/#define M 200/**这些都是一些全局数组,当时只是写了加法,其他的都是后来一时有兴趣写的,所以没有把数组放到函数里面。而且数组这么大,放进去不太好*/char op_1[M+1]={0};char op_2[M+1]={0};char result[2*(M+1)]={0};//积的位数最多为乘数中位数较大的二倍char result_div[2*(M+1)]={'0'};char div_tem[M+1]="1";/**对两个数加减的时候,位数不想等的时候要保证又对齐,不论什么情况都是从右向左操作的,为了防止数组向左越界,必须处理,可以每次都在程序判断哪一个存储数据的数组下标到0了,到0后就加0,也可以上来就把两个补齐变成一样长的,以后不用处理了。*/int init(char*add_1,char *add_2){    int i=0,off;   if(strlen(add_1)>strlen(add_2))   {       off=strlen(add_1)-strlen(add_2);       for(i=strlen(add_2)-1;i>=0;i--)       {           add_2[i+off]=add_2[i];       }       for(i=0;i<off;i++)       {           add_2[i]='0';       }   }   if(strlen(add_2)>strlen(add_1))   {       off=strlen(add_2)-strlen(add_1);       for(i=strlen(add_1)-1;i>=0;i--)       {           add_1[i+off]=add_1[i];       }       for(i=0;i<off;i++)       {           add_1[i]='0';       }   }   return strlen(add_2);}/**加法很好求,就是小学生竖式运算,按步骤来就行*/void calculate_add(char*add_1,char *add_2){   int r=0,i,j,len;   len=init(add_1,add_2)-1;   for(i=len,j=0,r=0;i>=0;i--,j++)   {       result[j]=(add_1[i]-'0'+add_2[i]-'0'+r)%10+'0';       r=(add_1[i]-'0'+add_2[i]-'0'+r)/10;   }   if(r!=0)   result[j]=r+'0';}/**减法很加法没有什么区别,无法就是一个负数,先根据补齐后的数组第一位的大小就可以判断大小,然后运算最后决定加不加负号就可以了*/void calculate_sub(char*Sub_1,char *Sub_2){    int i,j,len,r=0,flag=0;    char *sub_1,*sub_2;    len=init(Sub_1,Sub_2)-1;    if(Sub_1[0]<Sub_2[0])/***第一处*/    {        sub_2=Sub_1;        sub_1=Sub_2;        flag=1;    }    else    {        sub_1=Sub_1;        sub_2=Sub_2;    }    for(i=len,j=0,r=0;i>=0;i--,j++)    {        if(sub_1[i]>=sub_2[i])        {            result[j]=sub_1[i]-sub_2[i]+'0';        }        else        {            if(sub_1[i]==('0'-1))//被借位前是0的情况            {                result[j]='9'-sub_2[i]+'0';            }            else            {                 result[j]=10+sub_1[i]-sub_2[i]+'0';            }            sub_1[i-1]=sub_1[i-1]-1;/**第一处保证这里不会越界小于0*/        }    }    if(result[j-1]=='0')//这里不同与加法的判断,加法可能出现比加数多一位的情况,所以是对result[j]做判断    result[j-1]='\0';//减法不会,所以对j-1进行操作,要的是消除多余的0    if(flag==1)//负号是附加信息,应该在前面所有操作完成后进行决定添加与否    result[strlen(result)]='-';}/**乘法本来想安装现实那样计算,但是如果真的按照现实计算需要一个很大的二维数组,浪费空间严重不说,而且要最后对数组的每一行进行错位累加,感觉很麻烦。时间空间都比较浪费。所以自己分析了下过程,每次计算都进行错位累加,即节省了时间也节省了空间*/void calculate_mul(char *mul_1,char *mul_2){    int i,j,k=0,off=-1,r=0;    int temp0;    for(i=strlen(mul_2)-1;i>=0;i--)    {        r=0;//进位的数值设置为0        off++;//偏移量每次都要加1,模拟手动计算的时候的每次错一位        k=0;        for(j=strlen(mul_1)-1;j>=0;j--)        {           if(result[k+off]==0)//数组原来的值没有变            {                result[k+off]=((mul_1[j]-'0')*(mul_2[i]-'0')+r)%10+'0';//计算                r=((mul_1[j]-'0')*(mul_2[i]-'0')+r)/10;            }            else//进行错位加法计算            {                temp0=result[k+off]-'0';                 result[k+off]=(result[k+off]-'0'+(mul_1[j]-'0')*(mul_2[i]-'0')+r)%10+'0';                 r=(temp0+(mul_1[j]-'0')*(mul_2[i]-'0')+r)/10;            }            k++;        }        if(r!=0)        {            result[k+off]='0'+r;        }    }}/**除法就没有那么好运了,想不出类似乘法的办法,本来想用现实那样进行试除,感觉那样运算不好。下面是打算进行用第一个数减去第二个数,计算减到负数的次数。就是结果,但是没有成功啊!!感觉这样其实效率也很低,每次都进行加1,数据特别大的时候时间肯定超时了,这种方法其实也不好*/int calculate_div(char *div_1,char *div_2){   int i,k=0;   memset(result,0,sizeof(result));   calculate_sub(div_1,div_2);   if(result[strlen(result)-1]=='-')//第一个数比第二个数小的时候   {       result[0]='0';       result[1]='\0';       return 1;   }   for(i=strlen(result)-1;i>=0;i--)//帮刚刚做的减法操作的result里的结果保存到div_1   {        div_1[k++]=result[i];   }   div_1[k]='\0';//不能忘记了结束标志   memset(result,0,sizeof(result));   calculate_add(result_div,div_tem);//因为上面不为0,所以要进行一次加一。   k=0;   for(i=strlen(result)-1;i>=0;i--)//帮刚刚做的减法操作的result里的结果保存到result_div   {        result_div[k++]=result[i];   }   result_div[k]='\0';   while(result[strlen(result)-1]!='-')   {       k=0;       memset(result,0,sizeof(result));//使用前要清零       calculate_sub(div_1,div_2);       for(i=strlen(result)-1;i>=0;i--)       {            div_1[k++]=result[i];       }       div_1[k]='\0';//不能忘记了结束标志       memset(result,0,sizeof(result));       calculate_add(result_div,div_tem);       k=0;       for(i=strlen(result)-1;i>=0;i--)       {            result_div[k++]=result[i];       }        result_div[k]='\0';   }}int main(){    int i;    printf("请输入第一个数:\n");    gets(op_1);    printf("请输入第二个数:\n");    gets(op_2);    /**四种运算选择一个,做测试还是成功的*/      //calculate_add(op_1,op_2);     // calculate_sub(op_1,op_2);      calculate_mul(op_1,op_2);    for(i=strlen(result)-1;i>=0;i--)    {        putchar(result[i]);    }    return 0;}<span style="font-weight: bold;"></span>

乘法的截图





0 0