大数加法
对于加法来说,思路和阶乘的一样,就是每一位每一位地依次来看。
首先把两个数都装进数组里,同时比较长度,(len1比len2长则之后只是依次加到len1长度),如果某位相加的结果>=10,则令m=1,否则m=0,让下一位记得加了之后再+m
代码via静之吾心
#include<stdio.h>
#include<string.h>
int x[100]={0},y[100]={0},z[105]={0};//将数组元素全部初始化为0
int main()
{
char a[100],b[100];//通过字符串对大数进行输入并储存
int len1,len2,len;
while(scanf("%s %s",a,b))
{
int i,j=0,k=0;
len1=strlen(a);
len2=strlen(b);
for(i=len1-1;i>=0;i--)//将两个字符串中的字符转化为数字,并倒序储存到数组中,即字符串为123456,则数组为654321
{
x[j]=a[i]-'0';
j++;
}
for(i=len2-1;i>=0;i--)
{
y[k]=b[i]-'0';
k++;
}
if(len1>len2)
len=len1;
else
len=len2;
i=0;//从最低位(个位)开始进行计算
int m=0;
for(i=0;i<len;i++)
{
z[i]=(x[i]+y[i]+m)%10;//将所得数的个位存到数组z[i]中去
if((x[i]+y[i]+m)>=10)
m=1;
else
m=0;
}
if((x[i-1]+y[i-1]+m)>=10)//判断最高位还需不需要进位
z[i]=1;
else
i=i-1;
for(;i>=0;i--)//到序输出数组
printf("%d",z[i]);
printf("\n");
}
return 0;
}
大数减法
要联系大数加法,在编程设计上注意的点:
①不管加法和减法,都是要依次看到两个数中的最长长度的位数上去。比如6012-12的结果还是要看到第四位去
②加法要进位,减法要借位。加法的进位有可能最高位还要进不知道多少位出去,所以要考虑到这一点。但减法的借位,如果默认a-b的a>b,则不存在最高位还需要去借位,这样可以简便很多运算,只需要在调用函数前去判断a>b即可,如果a<b则先输出一个负号再交换a,b参数顺序即可。
③加法不需要考虑结果的前导0,而减法要考虑比如6012-6010=0002这种情况,输出的时候不要输出前导0.
AC代码:
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int x,y; //要求x-y
int a[500],b[500];
void sub(int a[],int b[],int len) //这里默认a是大于b的,具体在主函数里进行case判断了
{
int jie = 0;
//从低位到高位依次对应相减,如果减不过就借位
for(int i=1;i<=len;i++)
{
int temp;
if(a[i]-jie<b[i])
{
jie = 1; //需要借位,给下一位的jie赋为1
temp = a[i]+10-b[i];
}
else
{
temp = a[i] - jie - b[i]; //注意,如果我用这种方法,则要先-jie,再jie=0
jie = 0;
}
a[i] = temp;
}
//注意这里不用像加法一样还要去考虑最高位有进位,因为已经默认a>b了,所以不存在最高位还需要借位的情况
//输出的时候要注意:有可能有前导0!!!!(而加法无需考虑
for(int i=len;i>=1;i--)
{
if(a[i]==0)
len--;
else
break;
}
for(int i=len;i>=1;i--)
cout<<a[i];
cout<<endl;
}
int main()
{
char sa[500],sb[500]; //建立字符数组,这样就可以方便直接调用函数来求长度
cin>>sa>>sb; //当作字符串输入
int len1 = strlen(sa);
int len2 = strlen(sb);
//char数组转换成int数组,方便运算
for(int i=len1;i>=1;i--) //从下标为1开始存储,方便看。注意从低位->高位的顺序存
a[i] = sa[len1-i] - '0';
for(int i=len2;i>=1;i--)
b[i] = sb[len2-i] - '0';
if(len1>len2) //被减数更大
sub(a,b,len1);
else if(len1<len2) //减数更大,结果为负数
{
cout<<"-";
sub(b,a,len2);
}
else if(len1==len2) //两个数相同长度,还是应该比较大小,不然不好确定符号
{
int a_bigger = 0;
for(int i=len1;i>=1;i--)
{
if(a[i]>b[i])
{
a_bigger = 1;
break;
}
}
if(a_bigger==1)//说明被减数更大
sub(a,b,len1);
else //说明减数更大
{
cout<<"-";
sub(b,a,len2);
}
}
return 0;
}
大数乘法
和阶乘的做法大体相同,但是注意,阶乘由于每个位可以乘上很大的数,所以num要一直保留且传下去,而对于乘法对应位的相乘,最多9*9=81,所以只需要把多出来的第二位的值加到下一位,本位保留个位的值即可。
这里要get到一个点:在第5位的数值为a,其实际含义是a*10000。所以,第i位和第j位的数相乘,实质是i位数*j位数=i*j位数,因此,其结果应该放在i*j位上。
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++)//进行进位 MAX是二者位数最长长度
{
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的前缀 因为用的位数是MAX*2,不一定真能达到这么长
{
if(z[i]==0)
continue;
else
break;
}
for(;i>=0;i--) //倒序输出
printf("%d",z[i]);
---------------------
作者:静之吾心
来源:CSDN
原文:https://blog.csdn.net/lisp1995/article/details/52316466
版权声明:本文为博主原创文章,转载请附上博文链接!
大数除法
代码逻辑并没有想象中那么难。实际上的“求商”就是被除数减去除数的倍数,倍数以10递减,直到最后剩下的数小于除数,则为余数。
以28536 除以23 为例来看一下:开始商为0。
先减去23 的1000 倍(先补0直至除数位数==被除数位数),就是23000,发现够减1 次,余下5536,于是商的值就增加1000;
然后用5536减去2300,发现够减2 次,余下936,于是商的值增加200,即1200;
再用936 减去230,够减4 次,余下16,于是商值增加40,即1240。
最后,发现余下的数比23小,即为余数,即28536 / 23 得1240余16。