最近写高精度写得有些烦,于是直接整了个高精度头文件。
不知道头文件怎样写的同学看这里:怎么用c++写一个自己的头文件?
头文件名字: c l e a r . h clear.h clear.h
包含函数:
clearplus(a,b);//高精加
clearmulti(a,b);//高精乘
cleardiv(a,b);//高精除
clearmod(a,b);//高精模
clearsqrt(a,b);//高精开根
//转载请注明出处。
#ifndef CLEAR_H
#define CLEAR_H
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN = 300+4;
const ll N=20010,mod=100000000,length=log(mod)/log(10);
ll m;
int d[100001],e[100001];
bool k,mm;
int tmp[MAXN] = {};//交换用字符串
int a[100001],b[100001],c[100001],t[100001],p;
long long numa[50005],numb[50005],aans[50005],l1,l2,l,cnt2;
int work(int o,char *O,int I)
{
char c, *D=O ;
if(o>0)
{
for(l=0;D[l];D[l++]-=10)
{
D[l++]-=120;
D[l]-=110;
while(!work(0,O,l))
D[l]+=20;
putchar((D[l]+1032)/20);
}
putchar(10);
}
else
{
c=o+(D[I]+82)%10-(I>l/2)*(D[I-l+I]+72)/10-9;
D[I]+=I<0 ? 0 : !(o=work(c/10,O,I-1))*((c+999)%10-(D[I]+92)%10);
}
return o;
}
int clearplus(char a[],char b[]){
l1=strlen(a);
l2=strlen(b);
for(int i=l1-1;i>=0;--i){
numa[l1-i-1]=a[i]-'0';
}
for(int i=l2-1;i>=0;--i){
numb[cnt2]=b[i]-'0';
cnt2++;
}
l=max(l1,l2);
for(int i=0;i<l;++i){
aans[i]+=numa[i]+numb[i];
aans[i+1]=aans[i]/10;
aans[i]%=10;
}
if(aans[l]) l++;
for(int i=l-1;i>=0;--i) printf("%d", aans[i]);
memset(numa,0,sizeof numa);
memset(numb,0,sizeof numb);
memset(aans,0,sizeof aans);
l1=l2=l=cnt2=0;
}
int clearmulti(char a[],char b[]){
l1=strlen(a);
l2=strlen(b);
for(int i=l1-1; i>=0; --i){
numa[l1-i-1]=a[i]-'0';
}
for(int i=l2-1; i>=0; --i){
numb[cnt2]=b[i]-'0';
cnt2++;
}
l=max(l1, l2);
for(int i=0; i<l1; ++i){
for(int j=0;j<l2;j++){
aans[i]+=(numa[i]*numb[j])*pow(10,j);
}
aans[i+1]=aans[i]/10;
aans[i]%=10;
}
if(aans[l]){
l++;
}
for(int i=l-1; i>=0; --i){
printf("%d", aans[i]);
}
memset(numa,0,sizeof numa);
memset(numb,0,sizeof numb);
memset(aans,0,sizeof aans);
l1=l2=l=cnt2=0;
}
int compare(int a[], int b[]) {
//索引为0的数据为数组长度
if (a[0]>b[0]) {
return 1;
} else if (a[0]<b[0]) {
return -1;
}
//逐位比较
for (int i=a[0]; i>0; i--) {
if (a[i]>b[i]) {
return 1;
} else if (a[i]<b[i]) {
return -1;
}
}
return 0;
}
void numcpy(int a[],int b[],int dest) {
//将数组右移,使两个数组右端对齐,形参q数组储存右移后的结果
for (int i=1;i<=a[0];i++) {
b[i+dest-1] =a[i];
}
b[0] = a[0]+dest-1;
}
int cleardiv(char s1[],char s2[]) {
//处理负数
bool flaga = false;//乘数a的符号
if ('-'==s1[0]) {
flaga = true;
strcpy(s1, &s1[1]);//删除负号
}
bool flagb = false;//乘数b的符号
if ('-'==s2[0]) {
flagb = true;
strcpy(s2, &s2[1]);//删除负号
}
//处理输出的负号
if (true==flaga && false==flagb) {
//商为负数
printf("-");
}
//处理乘数1
int len = strlen(s1);
a[0] = len;
for (int i=0; i<len; i++) {
a[len-i]=s1[i]-'0';
}
//处理乘数2
len = strlen(s2);
b[0] = len;
for (int i=0; i<len; i++) {
b[len-i]=s2[i]-'0';
}
if (0==compare(a,b)) {
//两数相等
printf("1\n0\n");
return 0;
} else if (-1==compare(a,b)) {
//被除数小,除数大
printf("0\n");//输出除数
if (true==flaga) {
printf("-");
}
printf("%s\n", s1);
return 0;
} else {
c[0] = a[0]-b[0]+1;
for (int i=c[0]; i>0; i--) {
memset(tmp, 0, sizeof(tmp));
//高位对齐
numcpy(b,tmp,i);
//
while (compare(a, tmp)>=0) {
c[i]++;
//减法
for (int j=1; j<=a[0]; j++) {
if (a[j]<tmp[j]) {
a[j+1]--;
a[j]+=10;
}
a[j]-=tmp[j];
}
int k=a[0];
while (a[k]==0) {
k--;
}
a[0]=k;
}
}
//控制最高位的0
while (c[0]>0 && c[c[0]]==0) {
c[0]--;
}
}
for (int i=c[0]; i>0; i--) {
printf("%d", c[i]);
}
memset(c,0,sizeof 0);
memset(numa,0,sizeof numa);
memset(numb,0,sizeof numb);
memset(aans,0,sizeof aans);
l1=l2=l=cnt2=0;
return 0;
}
int clearsub(char a[],char b[]){
l1=strlen(a);
l2=strlen(b);
p=l2;
for(int i=0;i<=l1;i++){
c[l1-i]=a[i]-'0';
}
for(int i=0;i<=l2;i++){
d[l2-i]=b[i]-'0';
}
if(l1>=l2){
p=l1;
for(int i=1;i<=p;i++){
swap(c[i],d[i]);
}
}
else{
mm=1;
}
for(int i=1;i<=p;i++){
swap(c[i],d[i]);
}
for(int i=p;i>=0;i--){
if (c[i]>d[i]){
break;
}
if(c[i]<d[i]){
k=1;
break;
}
}
if(k){
mm=1;
for(int i=0;i<p;i++){
swap(c[i],d[i]);
}
}
for(int i=0;i<=p;i++){
e[i]+=c[i]-d[i];
if(e[i]<0){
e[i]+=10;
e[i+1]-=1;
}
}
k=0;
if(mm){
cout<<"-";
}
for(int i=0;i<p;i++){
if(e[p-i]!=0||i==p-1){
k=1;
}
if(k){
cout<<e[p-i];
}
}
return 0;
}
int clearmod(char s1[],char s2[]){
//处理负数
bool flaga = false;//乘数a的符号
if ('-'==s1[0]) {
flaga = true;
strcpy(s1, &s1[1]);//删除负号
}
bool flagb = false;//乘数b的符号
if ('-'==s2[0]) {
flagb = true;
strcpy(s2, &s2[1]);//删除负号
}
//处理输出的负号
if (true==flaga && false==flagb) {
//商为负数
printf("-");
}
//处理乘数1
int len = strlen(s1);
a[0] = len;
for (int i=0; i<len; i++) {
a[len-i]=s1[i]-'0';
}
//处理乘数2
len = strlen(s2);
b[0] = len;
for (int i=0; i<len; i++) {
b[len-i]=s2[i]-'0';
}
if (0==compare(a,b)) {
//两数相等
printf("1\n0\n");
return 0;
} else if (-1==compare(a,b)) {
//被除数小,除数大
printf("0\n");//输出除数
if (true==flaga) {
printf("-");
}
printf("%s\n", s1);
return 0;
} else {
c[0] = a[0]-b[0]+1;
for (int i=c[0]; i>0; i--) {
memset(tmp, 0, sizeof(tmp));
//高位对齐
numcpy(b,tmp,i);
//
while (compare(a, tmp)>=0) {
c[i]++;
//减法
for (int j=1; j<=a[0]; j++) {
if (a[j]<tmp[j]) {
a[j+1]--;
a[j]+=10;
}
a[j]-=tmp[j];
}
int k=a[0];
while (a[k]==0) {
k--;
}
a[0]=k;
}
}
//控制最高位的0
while (c[0]>0 && c[c[0]]==0) {
c[0]--;
}
}
if (0==a[0]) {
printf("0\n");
} else {
if (true==flaga) {
printf("-");
}
for (int i=a[0]; i>0; i--) {
printf("%d", a[i]);
}
}
memset(c,0,sizeof 0);
memset(numa,0,sizeof numa);
memset(numb,0,sizeof numb);
memset(aans,0,sizeof aans);
l1=l2=l=cnt2=0;
return 0;
}
int clearsqrt(char s[]){
l=0;s[0]='0';
scanf("%s",s+1);
if(strlen(s)%2 == 1)
work(2,s+1,0);
else
work(2,s,0);
}
#endif
使用方法:
#include<bits/stdc++.h>
#include "clear.h"
using namespace std;
char aa[5005],bb[5005],cc[5005];
int n;
int main(){
cin>>aa>>bb;
clearplus(aa,bb);
cout<<endl;
clearmulti(aa,bb);
cout<<endl;
cleardiv(aa,bb);
cout<<endl;
clearmod(aa,bb);
cout<<endl;
clearsub(aa,bb);
cout<<endl;
clearsqrt(cc);
return 0;
}