高精度加法:
#include<iostream>
#include<cstring>
using namespace std;
string sa,sb;
int a[100],b[100],c[100],lena,lenb,lenc,jw;
int main() {
cin>>sa;
cin>>sb; //读入数字a和b,将其存入字符串sa和sb中
lena=sa.size();
lenb=sb.size(); //求出2个数字的位数长度
lenc=lena;
if (lenb>lena) lenc=lenb; //lenc存放a、b中较大位数长度
for (int i=0;i<lena;i++) a[i]=sa[lena-i-1]-48;
for (int i=0;i<lenb;i++) b[i]=sb[lenb-i-1]-48;
//将字符串中的存储的数字字符转换为数字逆序存于a、b数组中
for (int i=0;i<lenc;i++) {
jw=jw+a[i]+b[i];
c[i]=jw%10;
jw=jw/10;
} //按位做加法,若有进位存于jw变量中
if (jw>0) c[lenc]=jw,lenc++; //若最高位有进位
for (int i=lenc-1;i>=0;i--) cout<<c[i]; //输出答案
return 0;
}
高精度减法:
#include<iostream>
#include<cstring>
using namespace std;
string sa,sb,t;
int a[100],b[100],c[100],lena,lenb;
int main() {
cin>>sa;
cin>>sb;
lena=sa.size();
lenb=sb.size();
if (lena<lenb || lena==lenb && sa<sb) t=sa,sa=sb,sb=t,cout<<'-'; //若a<b,先交换a、b的值,再输出负号
//若a、b位数相等可以直接字符串比较大小,若位数不等可通过位数来比较大小
lena=sa.size();
lenb=sb.size();
for (int i=0;i<lena;i++) a[i]=sa[lena-i-1]-48;
for (int i=0;i<lenb;i++) b[i]=sb[lenb-i-1]-48;
for (int i=0;i<lena;i++) {
c[i]=a[i]-b[i];
if (c[i]<0) c[i]+=10,a[i+1]--; //若不够减,向上借位
}
while (!c[lena-1] && lena>1) lena--; //去除前导零,需注意答案为零的情况
for (int i=lena-1;i>=0;i--) cout<<c[i]; //输出答案
return 0;
}
高精度乘法:
#include<iostream>
#include<cstring>
using namespace std;
string sa,sb;
int a[100],b[100],c[100],lena,lenb,lenc;
int main() {
cin>>sa;
cin>>sb; //读入数字a和b,将其存入字符串sa和sb中
lena=sa.size();
lenb=sb.size(); //求出2个数字的位数长度
for (int i=1;i<=lena;i++) a[i]=sa[lena-i]-48;
for (int i=1;i<=lenb;i++) b[i]=sb[lenb-i]-48;
//将字符串中的存储的数字字符转换为数字逆序存于a、b数组中
//a、b数组是从第1格开始存储,方便后续计算
for (int i=1;i<=lena;i++)
for (int j=1;j<=lenb;j++) {
c[i+j-1]+=a[i]*b[j];
c[i+j]+=c[i+j-1]/10;
c[i+j-1]%=10;
}
lenc=lena+lenb;
while (c[lenc]==0 && lenc>1) lenc--;
//从高位开始找非零值,确定乘积的位数
for (int i=lenc;i>0;i--) cout<<c[i]; //输出答案
return 0;
}
高精度乘方:
计算 x 的 n 次方
#include<iostream>
#include<cmath>
using namespace std;
int x,n,lx,s[100],len,jw,t;
int main() {
cin>>x>>n;
lx=floor(log(x)/log(10))+1; //计算x的位数
s[1]=1;
for (int i=0;i<n;i++) {
len+=lx;
jw=0;
for (int j=1;j<=len;j++)
t=s[j]*x+jw,jw=t/10,s[j]=t%10;
}
t=floor(n*log(x)/log(10))+1; //计算答案的位数
for (int i=t;i>0;i--) cout<<s[i];
return 0;
}
高精度乘方(快速幂):
计算 x 的 n 次方
#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
int x,n,a[100],b[100],len;
void ksm(int p) {
if (p==0) return;
ksm(p/2);
for (int i=1;i<=len;i++)
for (int j=1;j<=len;j++)
if (p%2==1) b[i+j-1]+=a[i]*a[j]*x;
else b[i+j-1]+=a[i]*a[j];
for (int i=1;i<=len;i++) {
b[i+1]+=b[i]/10;
a[i]=b[i]%10;
}
memset(b,0,sizeof(b));
}
int main() {
cin>>x>>n;
len=floor(n*log(x)/log(10)+1); //floor(n*log10(x)+1)也可
a[1]=1;
ksm(n);
for (int i=len;i>0;i--)
cout<<a[i];
return 0;
}
高精度实数加法:
#include<iostream>
#include<cstring>
using namespace std;
string s1,s2;
int zs1,xs1,zs2,xs2,len,a[100],b[100],zs,xs;
int main() {
cin>>s1>>s2;
//根据有没有小数点,区分整数和实数二种情况
//分别计算整数部分位数和小数部分位数,并删除小数点
if (s1.find(".")==string::npos) zs1=s1.size();
else zs1=s1.find("."),xs1=s1.size()-zs1-1,s1.erase(zs1,1);
if (s2.find(".")==string::npos) zs2=s2.size();
else zs2=s2.find("."),xs2=s2.size()-zs2-1,s2.erase(zs2,1);
//对于整数位数较小的数,前面补零,使其整数部分位数与另一个数相等
//对于小数位数较小的数,后面补零,使其小数部分位数与另一个数相等
if (zs1<zs2) for (int i=1;i<=zs2-zs1;i++) s1="0"+s1;
else for (int i=1;i<=zs1-zs2;i++) s2="0"+s2;
if (xs1<xs2) for (int i=1;i<=xs2-xs1;i++) s1=s1+"0";
else for (int i=1;i<=xs1-xs2;i++) s2=s2+"0";
//cout<<s1<<endl<<s2<<endl;
if (zs1>zs2) zs=zs1;
else zs=zs2;
if (xs1>xs2) xs=xs1;
else xs=xs2;
len=zs+xs; //当前字串长度
//将2个字串逆序反转存于a、b数组中
for (int i=1;i<=len;i++) a[i]=s1[i-1]-48;
for (int i=1;i<=len;i++) b[i]=s2[i-1]-48;
//高精加,并加结果存于a数组中
for (int i=len;i>0;i--) a[i]+=b[i],a[i-1]+=a[i]/10,a[i]%=10;
while (a[len]==0 && len>zs) len--; //删除小数部分后缀零
if (a[0]) cout<<a[0]; //若最高位有进位
for (int i=1;i<=zs;i++) cout<<a[i]; //输出整数部分
if (len>zs) { //若进位后小数部分有非零值
cout<<'.';
for (int i=zs+1;i<=len;i++) cout<<a[i];
}
return 0;
}
高精度除法:
#include<iostream>
#include<algorithm>
using namespace std;
string sa,sb;
int a[100],b[100],c[100],ans[100];
bool big() {
if (c[0]>b[0]) return true;
if (c[0]<b[0]) return false;
for (int i=c[0];i>=1;i--)
if (c[i]>b[i]) return true;
else if (c[i]<b[i]) return false;
return true; //相等的情况
}
void jian() {
int jw=0; //借位
for (int i=1;i<=c[0];i++) {
c[i]-=b[i]+jw;
if (c[i]<0) c[i]+=10,jw=1;
else jw=0;
}
while (c[0]>1 && c[c[0]]==0) c[0]--;
}
int main() {
cin>>sa; //读入第1个数,将其反转存于a数组中
a[0]=sa.size();
for (int i=1;i<=a[0];i++) a[i]=sa[i-1]-48;
reverse(a+1,a+1+a[0]);
cin>>sb; //读入第2个数,将其反转存于b数组中
b[0]=sb.size();
for (int i=1;i<=b[0];i++) b[i]=sb[i-1]-48;
reverse(b+1,b+1+b[0]);
//按竖式除法原理,构造c数组,只要够减,就不断c-b
for (int i=a[0];i>=1;i--) {
for (int j=c[0];j>=1;j--) c[j+1]=c[j];
c[1]=a[i];
if (c[c[0]+1]>0) c[0]++;
while (big()) jian(),ans[i]++;
}
ans[0]=a[0];
while (ans[0]>1 && ans[ans[0]]==0) ans[0]--;
for (int i=ans[0];i>=1;i--) cout<<ans[i]; //输出商
cout<<endl;
for (int i=c[0];i>=1;i--) cout<<c[i]; //输出余数
return 0;
}
大整数开方:
输入一个正整数 n,用二分法计算它的平方根的整数部分。
/*简版代码
#include<iostream>
using namespace std;
int target,z,mid,y;
int main() {
cin>>target;
z=1;
y=target;
while (y-z>1) {
mid=(z+y)/2;
if (mid*mid>target) y=mid; //大了
else z=mid; //小了
}
cout<<z;
return 0;
}
*/
#include<iostream>
#include<cstring>
using namespace std;
struct ds {
int len,num[100];
};
string s;
ds target,z,mid,y;
ds times(ds a,ds b) {
ds ans;
memset(ans.num,0,sizeof(ans.num));
for (int i=1;i<=a.len;i++)
for (int j=1;j<=b.len;j++)
ans.num[i+j-1]+=a.num[i]*b.num[j];
for (int i=1;i<=a.len+b.len;i++) {
ans.num[i+1]+=ans.num[i]/10;
ans.num[i]%=10;
}
if (ans.num[a.len+b.len]>0) ans.len=a.len+b.len;
else ans.len=a.len+b.len-1;
return ans;
}
ds add(ds a,ds b) {
ds ans;
memset(ans.num,0,sizeof(ans.num));
if (a.len>b.len) ans.len=a.len;
ans.len=b.len;
for (int i=1;i<=ans.len;i++) {
ans.num[i]=a.num[i]+b.num[i];
ans.num[i+1]+=ans.num[i]/10;
ans.num[i]%=10;
}
if (ans.num[ans.len+1]>0) ans.len++;
return ans;
}
ds average(ds a,ds b) {
ds ans;
ans=add(a,b);
for (int i=ans.len;i=2;i--) {
ans.num[i-1]+=ans.num[i]%2*10;
ans.num[i]/=2;
}
ans.num[1]/=2;
if (ans.num[ans.len]==0) ans.len--;
return ans;
}
ds plustwo(ds a){
ds ans;
ans=a;
ans.num[1]+=2;
int i=1;
while (ans.num[i]>=10) {
ans.num[i+1]+=ans.num[i]/10;
ans.num[i]%=10;
i++;
}
if (ans.num[ans.len+1]>0) ans.len++;
return ans;
}
bool over(ds a,ds b) { //判断a大于b吗?
if (a.len<b.len) return false;
if (a.len>b.len) return true;
for (int i=a.len;i>=1;i--)
if (a.num[i]<b.num[i]) return false;
else if (a.num[i]>b.num[i]) return true;
return false; //每个数位都相等
}
int main() {
cin>>s;
target.len=s.size();
for (int i=1;i<=target.len;i++) target.num[i]=s[target.len-i]-48;
z.len=1;
z.num[1]=1;
y=target;
while (!over(plustwo(z),y)) {
mid=average(z,y);
if (over(times(mid,mid),target)) y=mid; //大了
else z=mid; //小了
}
for (int i=z.len;i>=1;i--) cout<<z.num[i];
return 0;
}