高精度运算模板
代码“借鉴”的文章:oi.wiki : 高精度
基础版
#include <iostream>
#include <cstring>
using namespace std;
const int LEN =1e4+5; //根据实际情况调整,表示最高位
char s[LEN];//用于读取的字符串
//初始化一个数为0
void clear(int n[])
{
memset(n,0,LEN*sizeof(int));
}
//判断a大还是b大
int compareTwo(int a[],int b[])
{
int i;
for (i = LEN-1; i > 0; i--)
{
if(a[i]>0 && b[i]==0)
return 1;
else if(b[i]>0 && a[i]==0)
return -1;
else if(a[i]>0 && b[i]>0)
break;
}
for (; i >= 0; i--)
{
if(a[i] == b[i])
continue;
else if(a[i]>b[i])
return 1;
else
return -1;
}
return 0;
}
//此函数用来判断除法是否应该跳到下一位去除
//减少重复判断a以dg位减去b是否能保持非负,len为b的长度
bool greater_eq(int a[],int b[],int dg,int len)
{
if(a[dg+len] != 0)//dg位来看a的部分远大于b,一定能减
return true;
for (int i = len-1; i >=0; i--)//从高位向低位判断
{
if(a[dg+i] > b[i]) return true;
else if(a[dg+i] < b[i]) return false;
}
}
//读取正整数,倒着存入数组,个位在左,向右为高位,也方便进位操作,得到的 n 数组 --->{ 个位 , 十位 , 百位 ……}
void read(int n[])
{
int len;
clear(n);
scanf("%s",s);
len = strlen(s);
for (int i = 0; i < len; i++)
{
n[len-i-1] = s[i]-'0';
}
}
//正整数相加
void add(int a[],int b[],int res[])
{
clear(res);
for (int i = 0; i < LEN-1 ; i++)
{
res[i] += a[i] + b[i];
if(res[i]>=10)
{
res[i+1] += 1;
res[i] -= 10;
}
}
}
//正整数减法,要求 a>=b
void sub(int a[],int b[],int res[])
{
clear(res);
for (int i = 0; i < LEN-1 ; i++)
{
res[i] += a[i] - b[i];
if(res[i] < 0)
{
res[i+1] -= 1;
res[i] += 10;
}
}
}
//输出正整数
void print(int n[])
{
int i = LEN-1;
for (; i >=1; i--)
if(n[i]!=0) break;
for (; i >=0 ; i--)
{
printf("%d",n[i]);
}
printf("\n");
}
//高精度正整数相乘,注意,对于位数限制为 LEN 的数,相乘后最高位为 2*LEN
void mul(int a[], int b[], int res[]) {
clear(res);
for (int i = 0; i < LEN-1; i++)
{
for (int j = 0; j <= i; j++)
{
res[i] += a[j] * b[i - j];
}//完成第i位的所有运算,如个位,就先只算a[0]*b[0],十位就计算a[1]*b[0]+a[0]*b[1]
if (res[i] >= 10)
{
res[i + 1] += res[i] / 10;
res[i] %= 10;
}
}
}
//高精度除法被除数应大于等于除数
void div(int a[],int b[],int res[],int rest[])
{
clear(res);
clear(rest);
//求得两数长度
int len_a,len_b;
for (len_a = LEN; len_a > 0; len_a--)
if(a[len_a-1] != 0) break;
for (len_b = LEN; len_b > 0; len_b--)
if(b[len_b-1] != 0) break;
if(len_b==0) return;//除数不为0
memcpy(rest , a , LEN*sizeof(int) );//复制出余数
for (int dg = len_a-len_b ; dg >=0 ; dg--)//当前运算位为a的dg
{
while(greater_eq(rest,b,dg,len_b))
{
//高精度,将余数rest减去一个 dg 位上的 b
for (int i = 0; i < len_b; i++)
{
rest[dg+i]-=b[i];
if(rest[dg+i]<0)
{
rest[dg+i] += 10;
rest[dg+i+1] -= 1;
}
}
//商在dg位上多1
res[dg]++;
}
}
}
int main()
{
int a[LEN];
int b[LEN];
int res[LEN];//结果(和、差、商、积
int rest[LEN];//余数
read(a);
read(b);
//+
add(a,b,res);
print(res);
//-
if(compareTwo(a,b)<0)
{
sub(b,a,res);
printf("-");
}
else
sub(a,b,res);
print(res);
//*
mul(a,b,res);
print(res);
//'/'
div(a,b,res,rest);
print(res);
print(rest);
}