求四个整数的和
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
private static Scanner sc;
public static void main(String[] args) {
Scanner cin=new Scanner(System.in);
int T=cin.nextInt();
while(T--!=0)
{
BigInteger a=cin.nextBigInteger();
BigInteger b=cin.nextBigInteger();
BigInteger c=cin.nextBigInteger();
BigInteger d=cin.nextBigInteger();
BigInteger e=new BigInteger("0");
e=e.add(a);
e=e.add(b);
e=e.add(c);
e=e.add(d);
System.out.println(e);
}
}
}
求多个大整数的和,遇到 0 结束。
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
private static Scanner sc;
public static void main(String[] args) {
Scanner cin=new Scanner(System.in);
BigInteger a=new BigInteger("0");
BigInteger c=new BigInteger("0");
while(cin.hasNext())
{
BigInteger b=cin.nextBigInteger();
//System.out.println("** "+b);
if(b.compareTo(c)==0)
break;
a=a.add(b);
}
System.out.println(a);
}
}
求浮点型大数的 n 次幂。
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Scanner;
public class Main {//helloword
private static Scanner sc;
public static void main(String[] args) {
Scanner cin=new Scanner(System.in);
while(cin.hasNext())
{
BigDecimal a=cin.nextBigDecimal();
int n=cin.nextInt();
BigDecimal ans=a.pow(n);
String res=ans.stripTrailingZeros().toPlainString(); //把小数点后末尾的零去掉
if(res.charAt(0)=='0') //如果小数点的整数位为0,条件成立
res=res.substring(1); //去掉字符串res的第一个字符
System.out.println(res);
}
}
}
(以下内容转自他人博客,代码正确性不敢保证)
一:加法
1、普通两个大数相加
代码如下:
#include <cstdio>
#include <cmath>
#include <cstring>
void fan(char s[])
{
char t;
int i,j;
for(i = 0,j = strlen(s)-1; i <= j; i++,j--)
{
t=s[i];
s[i]=s[j];
s[j]=t;
}
}
int main()
{
int p = 0, g = 0,h = 1;
int k, l;
char x[100010], y[100010], z[100010];
while(scanf("%s%s",x,y)!=EOF)
{
p = 0;
fan(x);
fan(y);
k = strlen(x);
l = strlen(y);
int i;
for(i = 0; i < k || i < l; i++)
{
if(i < k && i < l )
z[i] = x[i]+y[i]+ p-'0';
else if(i < k && i >= l)
z[i] = x[i]+p;
else if(i >= k && i < l)
z[i] = y[i]+p;
if(z[i] > '9')
{
z[i]-=10;
p = 1;
}
else
p = 0;
}
if(p)
z[i++] = '1';
z[i] = '\0';
fan(x);
fan(y);
fan(z);
printf("%s + %s = %s\n",x,y,z);
}
return 0;
}
//flyzer 代码正确
//HDU 6225 AC code
//大整数加法函数形式
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<cstdlib>
#define ll long long
#define ull unsigned long long
#define mem(a,x) memset((a),(x),sizeof ((a)))//x只能是0或-1或false或true
#define debug(x) cout<<"X: "<<(x)<<endl
#define de cout<<"************"<<endl
#define lowbit(x) ((x)&(-x))
#define lson rt<<1
#define rson rt<<1|1
#define gcd(a,b) __gcd(a,b)
#define lcm(a,b) a*b/(__gcd(a,b))
#define inf 0x3f3f3f3f//1e9+6e7
#define eps 1e-8
#define mod 1e9+7
#define N 1000010
const double pi=acos(-1.0);
using namespace std;
void fan(char s[])
{
char t;
int i,j;
for(i = 0,j = strlen(s)-1; i <= j; i++,j--)
{
t=s[i];
s[i]=s[j];
s[j]=t;
}
}
int doo(char x[],char y[],char z[]) //把x+y的结果储存到z中
{
int p = 0, g = 0,h = 1;
int k, l;
p = 0;
fan(x);
fan(y);
k = strlen(x);
l = strlen(y);
int i;
for(i = 0; i < k || i < l; i++)
{
if(i < k && i < l )
z[i] = x[i]+y[i]+ p-'0';
else if(i < k && i >= l)
z[i] = x[i]+p;
else if(i >= k && i < l)
z[i] = y[i]+p;
if(z[i] > '9')
{
z[i]-=10;
p = 1;
}
else
p = 0;
}
if(p)
z[i++] = '1';
z[i] = '\0';
fan(x);
fan(y);
fan(z);
}
int main()
{
int T;
cin>>T;
char a[100],b[100],c[100],d[100];
char ans1[100],ans2[100],ans3[110];
while(T--)
{
mem(ans1,0);
mem(ans2,0);
mem(ans3,0);
scanf("%s%s%s%s",a,b,c,d);
doo(a,b,ans1);
doo(c,d,ans2);
doo(ans1,ans2,ans3);
cout<<ans3<<endl;
}
return 0;
}
2、多个大数相加://poj 1503
//POJ 1503 AC code
//代码正确
#include <cstdio>
#include <cstring>
const int MAXN = 117;
int main()
{
char s[MAXN];
int sum[MAXN] = {0};
int i, j;
while(gets(s))
{
int len = strlen(s);
if(s[0] == '0' && len == 1)
break;
for(i = 110, j = len-1; j >= 0; i--, j--)
{
sum[i] += s[j]-'0';
}
}
for(i = 110; i > 0; i--)
{
sum[i-1] += sum[i] / 10;
sum[i] %= 10;
}
for(i = 0; sum[i] == 0 && i < 111; i++)
{
if(i == 111)//意味着全为零
{
printf("0\n");
}
}
for( ; i < 111; i++)
{
printf("%d",sum[i]);
}
printf("\n");
return 0;
}
二:大数乘法
1、普通模拟乘法(char )
代码如下://POJ 2389 ζёСяêτ - 小優YoU 小優YoU
//POJ 2389 AC code
//代码正确
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
const int size = 1000; //大数位数
void mult(char* A,char* B,char* ans)
{
int a[size+1]= {0};
int b[size+1]= {0};
int pa=0,pb=0;
int c[2*size+1]= {0};
int lena=strlen(A);
int lenb=strlen(B);
for(int i=lena-1; i>=0; i--)
a[pa++]=A[i]-'0';
for(int j=lenb-1; j>=0; j--)
b[pb++]=B[j]-'0';
for(pb=0; pb<lenb; pb++)
{
int w=0; //低位到高位的进位
for(pa=0; pa<=lena; pa++)
{
int temp=a[pa]*b[pb]+w;
w=temp/10;
temp=(c[pa+pb]+=temp%10);
c[pa+pb]=temp%10;
w+=temp/10;
}
}
bool flag=false;
bool sign=false; //标记ans是否为全0
for(pa=0,pb=lena+lenb-1; pb>=0; pb--)
{
if(!flag && c[pb]==0) //删除ans开头的0
continue;
else
flag=true;
sign=true;
ans[pa++]=c[pb]+'0';
}
if(sign)
ans[pa]='\0';
else
{
ans[0]='0';
ans[1]='\0';
}
return;
}
int main()
{
char a[size+1];
char b[size+1];
char ans[2*size+1];
while(cin>>a>>b)
{
mult(a,b,ans);
cout<<ans<<endl;
}
return 0;
}
2、(string)
代码如下:http://blog.csdn.net/y990041769/article/details/20116995
string sum(string s1,string s2) //大数加法
{
if(s1.length()<s2.length())
{
string temp=s1;
s1=s2;
s2=temp;
}
int i,j;
for(i=s1.length()-1,j=s2.length()-1;i>=0;i--,j--)
{
s1[i]=char(s1[i]+(j>=0?s2[j]-'0':0)); //注意细节
if(s1[i]-'0'>=10)
{
s1[i]=char((s1[i]-'0')%10+'0');
if(i) s1[i-1]++;
else s1='1'+s1;
}
}
return s1;
}
string Mult(string s,int x) //大数乘以整形数
{
reverse(s.begin(),s.end());
int cmp=0;
for(int i=0;i<s.size();i++)
{
cmp=(s[i]-'0')*x+cmp;
s[i]=(cmp%10+'0');
cmp/=10;
}
while(cmp)
{
s+=(cmp%10+'0');
cmp/=10;
}
reverse(s.begin(),s.end());
return s;
}
string Multfa(string x,string y) //大数乘法
{
string ans;
for(int i=y.size()-1,j=0;i>=0;i--,j++)
{
string tmp=Mult(x,y[i]-'0');
for(int k=0;k<j;k++)
tmp+='0';
ans=sum(ans,tmp);
}
return ans;
}
3、(FFT 傅里叶高效算法)
代码如下://HDU1402 kuangbin
//HDU 1402 AC code
//代码正确
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <math.h>
using namespace std;
const double PI = acos(-1.0);
//复数结构体
struct complex
{
double r,i;
complex(double _r = 0.0,double _i = 0.0)
{
r = _r;
i = _i;
}
complex operator +(const complex &b)
{
return complex(r+b.r,i+b.i);
}
complex operator -(const complex &b)
{
return complex(r-b.r,i-b.i);
}
complex operator *(const complex &b)
{
return complex(r*b.r-i*b.i,r*b.i+i*b.r);
}
};
/*
* 进行FFT和IFFT前的反转变换。
* 位置i和 (i二进制反转后位置)互换
* len必须去2的幂
*/
void change(complex y[],int len)
{
int i,j,k;
for(i = 1, j = len/2; i < len-1; i++)
{
if(i < j)swap(y[i],y[j]);
//交换互为小标反转的元素,i<j保证交换一次
//i做正常的+1,j左反转类型的+1,始终保持i和j是反转的
k = len/2;
while( j >= k)
{
j -= k;
k /= 2;
}
if(j < k) j += k;
}
}
/*
* 做FFT
* len必须为2^k形式,
* on==1时是DFT,on==-1时是IDFT
*/
void fft(complex y[],int len,int on)
{
change(y,len);
for(int h = 2; h <= len; h <<= 1)
{
complex wn(cos(-on*2*PI/h),sin(-on*2*PI/h));
for(int j = 0; j < len; j+=h)
{
complex w(1,0);
for(int k = j; k < j+h/2; k++)
{
complex u = y[k];
complex t = w*y[k+h/2];
y[k] = u+t;
y[k+h/2] = u-t;
w = w*wn;
}
}
}
if(on == -1)
for(int i = 0; i < len; i++)
y[i].r /= len;
}
const int MAXN = 200010;
complex x1[MAXN],x2[MAXN];
char str1[MAXN/2],str2[MAXN/2];
int sum[MAXN];
int main()
{
while(scanf("%s%s",str1,str2)==2)
{
int len1 = strlen(str1);
int len2 = strlen(str2);
int len = 1;
while(len < len1*2 || len < len2*2)len<<=1;
for(int i = 0; i < len1; i++)
x1[i] = complex(str1[len1-1-i]-'0',0);
for(int i = len1; i < len; i++)
x1[i] = complex(0,0);
for(int i = 0; i < len2; i++)
x2[i] = complex(str2[len2-1-i]-'0',0);
for(int i = len2; i < len; i++)
x2[i] = complex(0,0);
//求DFT
fft(x1,len,1);
fft(x2,len,1);
for(int i = 0; i < len; i++)
x1[i] = x1[i]*x2[i];
fft(x1,len,-1);
for(int i = 0; i < len; i++)
sum[i] = (int)(x1[i].r+0.5);
for(int i = 0; i < len; i++)
{
sum[i+1]+=sum[i]/10;
sum[i]%=10;
}
len = len1+len2-1;
while(sum[len] <= 0 && len > 0)len--;
for(int i = len; i >= 0; i--)
printf("%c",sum[i]+'0');
printf("\n");
}
return 0;
}
三:大数除法
1(string)大数除以整形数
代码如下:
string Except(string s,int x) //大数除以整形数
{
int cmp=0,ok=0;
string ans="";
for(int i=0;i<s.size();i++)
{
cmp=(cmp*10+s[i]-'0');
if(cmp>=x)
{
ok=1;
ans+=(cmp/x+'0');
cmp%=x;
}
else{
if(ok==1)
ans+='0'; //注意这里
}
}
return ans;
}
四、浮点大数求幂
代码如下:ζёСяêτ - 小優YoU
//POJ 1001 AC code
//代码正确
#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
using namespace std;
const int size=1000; //大数位数
void mult(char* A,char* B,char* ans)
{
int i,j,k;
int fract; //总小数个数
int dot=-1; //小数点位置
for(k=0; A[k]!='\0'; k++)
if(A[k]=='.')
dot=k;
int lena=k;
if(dot==-1)
fract=0;
else
fract=lena-dot-1;
dot=-1;
for(k=0; B[k]!='\0'; k++)
if(B[k]=='.')
dot=k;
int lenb=k;
if(dot==-1)
fract+=0;
else
fract+=(lenb-dot-1); //总小数个数
int a[size+1]= {0};
int b[size+1]= {0};
int pa=0,pb=0;
/*倒序*/
for(i=lena-1; i>=0; i--)
{
if(A[i]=='.')
continue;
a[pa++]=A[i]-'0';
}
for(j=lenb-1; j>=0; j--)
{
if(B[j]=='.') //暂时删除小数点
continue;
b[pb++]=B[j]-'0';
}
int c[2*size+1]= {0};
int lenc;
for(pb=0; pb<lenb; pb++)
{
int w=0; //低位到高位的进位
for(pa=0; pa<=lena; pa++) // = 为了处理最后的进位
{
int temp=a[pa]*b[pb]+w;
w=temp/10;
temp=(c[pa+pb]+=temp%10);
c[lenc=pa+pb]=temp%10;
w+=temp/10;
}
}
/*倒序,得到没有小数点的ans*/
for(pa=0,pb=lenc; pb>=0; pb--)
ans[pa++]=c[pb]+'0';
ans[pa]='\0';
lena=pa;
/*插入小数点*/
bool flag=true; //标记是否需要删除小数末尾的0
if(fract==0) //小数位数为0,无需插入小数点
flag=false;
else if(fract<lena) //小数位数小于ans长度,在ans内部插入小数点
{
ans[lena+1]='\0';
for(i=0,pa=lena; pa>0; pa--,i++)
{
if(i==fract)
{
ans[pa]='.';
break;
}
else
ans[pa]=ans[pa-1];
}
}
else //小数位数大于等于ans长度,在ans前面恰当位置插入小数点
{
char temp[size+1];
strcpy(temp,ans);
ans[0]='0';
ans[1]='.';
for(int i=0; i<fract-lena; i++) //补充0
ans[i+2]='0';
for(j=i,pa=0; pa<lena; pa++)
ans[j++]=temp[pa];
ans[j]='\0';
}
/*删除ans小数末尾的0*/
if(flag)
{
lena=strlen(ans);
pa=lena-1;
while(ans[pa]=='0')
ans[pa--]='\0';
if(ans[pa]=='.') //小数全为0
ans[pa--]='\0';
}
/*删除ans整数开头的0,但至少保留1个0*/
pa=0;
while(ans[pa]=='0') //寻找ans开头第一个不为0的位置
pa++;
if(ans[pa]=='\0') //没有小数
{
ans[0]='0';
ans[1]='\0';
}
else //有小数
{
for(i=0; ans[pa]!='\0'; i++,pa++)
ans[i]=ans[pa];
ans[i]='\0';
}
return;
}
char a[size+1];
char ans[size*size+1];
int main(void)
{
int b;
while(cin>>a>>b)
{
memset(ans,'\0',sizeof(ans));
ans[0]='1';
ans[3]='\0';
for(int i=1; i<=b; i++)
mult(a,ans,ans);
cout<<ans<<endl;
}
return 0;
}
高精度四则运算模板
大数模版
/*大数加法*/
# include<stdio.h>
# include<string.h>
# include<malloc.h>
void add(char* a,char* b,char* c)
{
int i,j,k,max,min,n,temp;
char *s,*pmax,*pmin;
max=strlen(a);
min=strlen(b);
if (max<min)
{
temp=max;
max=min;
min=temp;
pmax=b;
pmin=a;
}
else
{
pmax=a;
pmin=b;
}
s=(char*)malloc(sizeof(char)*(max+1));
s[0]='0';
for (i=min-1,j=max-1,k=max;i>=0;i--,j--,k--)
s[k]=pmin[i]-'0'+pmax[j];
for (;j>=0;j--,k--)
s[k]=pmax[j];
for (i=max;i>=0;i--)
if (s[i]>'9')
{
s[i]-=10;
s[i-1]++;
}
if (s[0]=='0')
{
for (i=0;i<=max;i++)
c[i-1]=s[i];
c[i-1]='\0';
}
else
{
for (i=0;i<=max;i++)
c[i]=s[i];
c[i]='\0';
}
free(s);
}
/*大数减法*/
void subtract(char* a,char* b,char* c)
{
int i,j,ca,cb;
ca=strlen(a);
cb=strlen(b);
if (ca>cb||(ca==cb&&strcmp(a,b)>=0))
{
for (i=ca-1,j=cb-1;j>=0;i--,j--)
a[i]-=(b[j]-'0');
for (i=ca-1;i>=0;i--)
if (a[i]<'0')
{
a[i]+=10;
a[i-1]--;
}
i=0;
while (a[i]=='0')
i++;
if (a[i]=='\0')
{
c[0]='0';
c[1]='\0';
}
else
{
for (j=0;a[i]!='\0';i++,j++)
c[j]=a[i];
c[j]='\0';
}
}
else
{
for (i=ca-1,j=cb-1;i>=0;i--,j--)
b[j]-=(a[i]-'0');
for (j=cb-1;j>=0;j--)
if (b[j]<'0')
{
b[j]+=10;
b[j-1]--;
}
j=0;
while (b[j]=='0')
j++;
i=1;
c[0]='-';
for (;b[j]!='\0';i++,j++)
c[i]=b[j];
c[i]='\0';
}
}
/* 大数乘法*/
void multiply(char* a,char* b,char* c)
{
int i,j,ca,cb,* s;
ca=strlen(a);
cb=strlen(b);
s=(int*)malloc(sizeof(int)*(ca+cb));
for (i=0;i<ca+cb;i++)
s[i]=0;
for (i=0;i<ca;i++)
for (j=0;j<cb;j++)
s[i+j+1]+=(a[i]-'0')*(b[j]-'0');
for (i=ca+cb-1;i>=0;i--)
if (s[i]>=10)
{
s[i-1]+=s[i]/10;
s[i]%=10;
}
i=0;
while (s[i]==0)
i++;
for (j=0;i<ca+cb;i++,j++)
c[j]=s[i]+'0';
c[j]='\0';
free(s);
}
/*大数除法,返回余数*/
int dividor(char* a,int b,char* c)
{
int i,j,temp=0,n;
char* s;
n=strlen(a);
s=(char*)malloc(sizeof(char)*(n+1));
for (i=0;a[i]!=0;i++)
{
temp=temp*10+a[i]-'0';
s[i]=temp/b+'0';
temp%=b;
}
s[i]='\0';
for (i=0;s[i]=='0'&&s[i]!='\0';i++);
if (s[i]=='\0')
{
c[0]='0';
c[1]='\0';
}
else
{
for (j=0;s[i]!='\0';i++,j++)
c[j]=s[i];
c[j]='\0';
}
free(s);
return temp;
}