一、大数相乘
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#include <iostream>
using namespace std;
int main()
{
char chr1[100],chr2[100];
int len1,len2;
while(scanf("%s %s",chr1,chr2))
{
int i,j=0,k=0,s;
int a[110]={0},b[110]={0},c[220]={0};
len1=strlen(chr1);
len2=strlen(chr2);
for(i=len1-1,j=0;i>=0;i--) a[j++]=chr1[i]-'0';
for(i=len2-1,k=0;i>=0;i--) b[k++]=chr2[i]-'0';
for(i=0;i<len1;i++)
{
for(s=0;s<len2;s++)
{
c[i+s]=c[i+s]+a[i]*b[s];
}
}
for(i=0;i<200;i++)
{
if(c[i]>=10){
c[i+1]=c[i+1]+c[i]/10; //这一步和下面一步位置不要写反了
c[i]=c[i]%10;
}
}
for(i=200;i>0;i--)
{
if(c[i]==0) continue;
else break;
}
for(;i>=0;i--) cout<<c[i];
cout<<endl;
}
return 0;
}
二、大数相除(取模,取余)(没有看懂)
#include<stdio.h>
#include<string.h>
char a[100],b[100];//用两个字符串用来输入两个大数
int x[100],y[100],z[100],m[100];//被除数 除数 商 余数
int digit;//大数的位数
void sub(int x[],int y[],int len1,int len2)//大数减法
{
int i;
for(i=0;i<len1;i++)
{
if(x[i]<y[i])
{
x[i]=x[i]+10-y[i];
x[i+1]--;
}
else
x[i]=x[i]-y[i];
}
for(i=len1-1;i>=0;i--)//判断减法结束之后,被除数的位数
{
if(x[i])
{
digit=i+1;
break;
}
}
}
int judge(int x[],int y[],int len1,int len2)
{
int i;
if(len1<len2)
return -1;
if(len1==len2)//若两个数位数相等
{
for(i=len1-1;i>=0;i--)
{
if(x[i]==y[i])//对应位的数相等
continue;
if(x[i]>y[i])//被除数 大于 除数,返回值为1
return 1;
if(x[i]<y[i])//被除数 小于 除数,返回值为-1
return -1;
}
return 0;//被除数 等于 除数,返回值为0
}
}
int main()
{
int i,j=0,k=0,temp;
int len1,len2,len;//len两个大数位数的差值
while(~scanf("%s %s",a,b))
{
len1=strlen(a);//被除数位数
len2=strlen(b);//除数位数
for(i=len1-1,j=0;i>=0;i--)//将字符串中各个元素倒序储存在数组中
x[j++]=a[i]-'0';
for(i=len2-1,k=0;i>=0;i--)
y[k++]=b[i]-'0';
if(len1<len2)//当被除数位数 小于 除数位数时
{
printf("商是:0
");
printf("余数是:");
puts(a);
}
else //当被除数位数 大于或者 除数位数时
{
len=len1-len2;//两个大数位数的差值
for(i=len1-1;i>=0;i--)//将除数后补零,使得两个大数位数相同。被除数:4541543329 除数:98745,加零后:9874500000
{
if(i>=len)
y[i]=y[i-len];
else
y[i]=0;
}
len2=len1;//将两个大数数位相同
digit=len1; //将原被除数位数赋值给digit
for(j=0;j<=len;j++)
{
z[len-j]=0;
while(((temp=judge(x,y,len1,len2))>=0)&&digit>=k)//判断两个数之间的关系以及位数与除数原位数的关系
{
sub(x,y,len1,len2); //大数减法函数
z[len-j]++;//储存商的每一位
len1=digit;//重新修改被除数的长度
if(len1<len2&&y[len2-1]==0)
len2=len1;//将len1长度赋给len2;
}
if(temp<0)//若被除数 小于 除数,除数减小一位。例如:被除数:4541543329 除数:(原)98745,(加零后)9874500000,后退一位后:0987450000
{
for(i=1;i<len2;i++)
y[i-1]=y[i];
y[i-1]=0;
if(len1<len2)
len2--;
}
}
printf("商是:");
for(i=len;i>0;i--)//去掉前缀0
{
if(z[i])
break;
}
for(;i>=0;i--)
printf("%d",z[i]);
printf("
");
printf("余数是:");
for(i=len1;i>0;i--)
{
if(x[i])
break;
}
for(;i>=0;i--)
printf("%d",x[i]);
printf("
");
}
}
return 0;
}
三、大数阶乘(求位数)
法一:
lg(N!)=[lg(N*(N-1)*(N-2)*......*3*2*1)]+1 =[lgN+lg(N-1)+lg(N-2)+......+lg3+lg2+lg1]+1
#include<stdio.h>
#include<math.h>
int main()
{
int n;
double sum=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
sum=sum+log10(i);
}
printf("%d
",(int)sum+1);
return 0;
}
法二:
log10(n!) = log10(2*PI*n)/2+n*log10(n/E);
故n!的位数= log10(2*PI*n)/2+n*log10(n/E)+1(注意:当n=1时,算得的结果为0)
#include<stdio.h>
#include<math.h>
#define PI 3.141592654
#define E 2.71828182846
int main()
{
int n,sum=1;
scanf("%d",&n);
if(n>3)
sum=log10(2*PI*n)/2+n*log10(n/E)+1;
printf("%d
",sum);
return 0;
}
四、大数阶乘(求值)
#include <cstdio>
#include <iostream>
using namespace std;
int main()
{
int n,a[20001];
int temp,digit=1;
a[0]=1;
cin>>n;
int i,j;
for(i=2;i<=n;i++)
{
int num=0;
for(j=0;j<digit;j++)
{
temp=a[j]*i+num;
a[j]=temp%10;
num=temp/10;
}
while(num)
{
a[digit]=num%10;
num/=10;
digit++;
}
}
for(i=digit-1;i>=0;i--) cout<<a[i];
cout<<endl;
return 0;
}
五、大数相减
//大数相减
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
int x[100]={0},y[100]={0},z[100]={0};
void sub(int x[],int y[],int len)
{
for(int i=0;i<len;i++)
{
if(x[i]>=y[i]) z[i]=x[i]-y[i];
else if(x[i]<y[i])
{
z[i]=x[i]+10-y[i];
x[i+1]=x[i+1]-1;
}
}
for(int i=len-1;i>0;i--)
{
if(z[i]==0) len--;
else break;
}
for(int i=len-1;i>=0;i--) cout<<z[i];
cout<<endl;
}
int main()
{
char chr1[100],chr2[100];
int len1,len2;
while(scanf("%s %s",chr1,chr2))
{
int i,j=0,k=0;
len1=strlen(chr1);
len2=strlen(chr2);
for(i=len1-1,j=0;i>=0;i--) x[j++]=chr1[i]-'0';
for(i=len2-1,k=0;i>=0;i--) y[k++]=chr2[i]-'0';
if(len1>len2) sub(x,y,len1);
else if(len1<len2)
{
printf("-");
sub(y,x,len2);
}
else if(len1==len2)
{
for(i=len1-1;i>=0;i--)
{
if(x[i]==y[i]) continue;
else if(x[i]>y[i])
{
sub(x,y,len1);
break;
}
else if(x[i]<y[i])
{
printf("-");
sub(y,x,len1);
break;
}
}
if(i==-1) sub(x,y,len1);
}
}
return 0;
}
六、大数相加
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
int main()
{
char chr1[100],chr2[100];
int a[100]={0},b[100]={0},c[100]={0};
int len1,len2,len;
while(scanf("%s %s",chr1,chr2))
{
int i,j=0,k=0;
len1=strlen(chr1);
len2=strlen(chr2);
for(i=len1-1;i>=0;i--)
{
a[j]=chr1[i]-'0';
j++;
}
for(i=len2-1;i>=0;i--)
{
b[k]=chr2[i]-'0';
k++;
}
if(len1>len2) len=len1;
else len=len2;
int m=0;
for(i=0;i<len;i++)
{
c[i]=(a[i]+b[i]+m)%10;
if(a[i]+b[i]+m>=10) m=1;
else m=0;
}
if(a[i-1]+b[i-1]+m>10) c[i]=1;
else i=i-1;
for(;i>=0;i--) cout<<c[i];
cout<<endl;
}
return 0;
}