超过20位的数 用longlong已经无法运算 所以采用str 或char数组保存
以下用big number表示大整数 bign
为了方便记录大整数的位数 一般采用结构体保存大整数
struct bign
{
int d[1000];
int len;
bign {
memset(d,0,sizeof(d));
len=0;
}// 直接对结构体进行初始化,这样在每次定义结构体变量时 会直接对该变量初始化
}
在用字符串读入之后 存入bign结构体中
bign change(char str[])
{
bign al;
a.len=strlen(str);
for(int i=0;i<a;i++){
a.d[i]=str[a.len-i-1]-'0';//**注意逆置 即123 存成321 因为在运算中一般从个位开始 这样有进位或退位比较方便 不用后移**
}
return a;
}
若要比较大小 则先比较len ,len大的大 而后从高位到低位比较即可
模拟小学的加法运算即可 (满十进一)
注意bign本身是逆序的 d【0】为个位
bign add(bing a,bign b)
{
bign c;
int carry=0;//进位
for(int i=0;i<a.len || i<b.len;i++){//以较长的为界限
int temp=a.d[i]+b.d[i]+carry;
c.d[c.len++]=temp%10;
carry=temp/10; //新的进位产生由temp产生
}
if(carry!=0)//**最后的进位为1 则要增加数组长度 直接赋值给最高位 且不用后移数组**
{
c.d[c.len++]=carry;
}
return c;
}
分步实现加法
int main()
{
char str1[100],str2[100];
scanf("%s%s",str1,str2);
bing a=change(str1);
bign b=change(str2);
bing c=add(a,b);
print(c); //自己定义一个print函数输出 这里就不写了哈
return 0;
}
原理 不够减,向高位借1 本身加10,高位减一 最高位可能退位
bign sub(bign a,bign b) //调用时默认a>b 使用时比较a b的大小
{
bign c;
for(int i=0;i<a.len||i<b.len;i++)
{
if(a.d[i]<b.d[i])//不够减
{
a.d[i+1]--;
a.d[i]+=10;
}
c.d[c.len]=a.d[i]-b.d[i];//当前位结果
c.len++;
}
while(c.len-1>=1 && c.d[c.len-1]==0){
c.len--;//去掉最高位的0 但至少保留一位数
}
return c;
}
低精度 就是可以用基本数据类型表示的数‘
相当于用印度那边的乘法计算方法 直接把低精度看成一个整体
对单步而言 取bign的某位和 低精度整体乘积 再与进位相加 所得的各位为结果,高位的是新的进位;
代码如下
bign multi(bign a,int b)//一个是int 型 注意
{
bign c;
int carry=0;//进位
for(int i=0;i<a.len;i++){
int temp=a.d[i]*b+carry;
c.d[c.len++]=temp%10; //本位
carry=temp/10; //高位
}
while(carry!=0)//**乘法的最后一个carry可能进很多位**
{
c.d[len++]=carry%10;
carry/=10;
}
return c;
}
模拟小学的除法 不够除 商为0,够除 则直接写 注意临时的被除数要加上上一步的余数乘10;
具体标注见代码
bign divide( bign a,int b)
{
bign c;
int r=0;//r是余数,初始为0 第一个之前没有余数 所以为0
c.len=a.len;//除数的每一位是和a一一对应的 先另长度相等
for(int i=a.len-1;i>=0;i--)//从高位开始
{
r=r*10+a.d[i];
if(r<b) c.d[i]=0;
else {
c.d[i]=r/b;
r=r%d;//新的余数
}
}
while(c.len-1>=1 &&c.d[c.len-1]==0) //处理高位0
{
c.len--;
}
return 0;
}