有时候,我们不免会遇到一些数据,它的范围超过了计算机本身所定义的int型和long型所能表示的范围,但我们又需要对这些数进行相应的运算,这时我们便需要用到高精度算法。
高精度处理,实际上就是模拟法,模拟手算,它的原理与我们用竖式计算时一样的,不过在处理过程中要注意高精度数据的读入、转换储存、数据的计算、结果位数的计算、输出等几个问题。高精度计算中需要处理如下几个问题:
1.数据的输入:由于数据都是十分大的数字,我们采用字符数组将它们接收。
2.数据的存储和计算:由于我们是直接通过字符数组将我们的数据存储的,不能够将它们直接进行计算,所以我们还需要转换存储方式,把字符串数组的数据存储到int型的数组里。(将数据存入整形数组时,可以将数组下标为1对应个位,也可以直接对应最高位。本文采取第一种方式。)
3.模拟竖式计算:无论是加减,还是乘除,都需要模拟竖式计算。竖式计算中,我们需要将每一位上的数对其,然后再进行加或减的运算,来最终确定每一位上的数,同时加法遵守逢十进一,减法数位不够减时向前借一。
代码展示
#include
#include
#include
int main(){
char t1[502], t2[502];
int i, j, k = 0, l1, l2, l3, max, f, s1[502] = {0}, s2[502] = {0}, s[502] = {0};//k存储进位
// gets(t1);使用gets()函数无法全部通过样例
// gets(t2);
scanf("%s",t1);
scanf("%s",t2);
l1 = strlen(t1);
l2 = strlen(t2);
max = (l1>l2) ? l1 : l2;//max保存大数的位数
for(i = 1;i <= l1; i++){
s1[i] = t1[l1 - i] - '0';//将个位数对其数组下标一
}
for(j = 1;j <= l2; j++){
s2[j] = t2[l2 - j] - '0';//将个位数对其数组下标一
}
for(i = 1;i <= max; i++){
f = s1[i] + s2[i] + k;
if(f >= 10){
k = f/10;//存储进位
s[i] = f % 10;
}
else{
s[i] = f;
k = 0;
}
}
if(k != 0){
s[++max] = k;//最高位满十进一
}
for(i = max; i >= 1; i--)
printf("%d",s[i]);//从最高位输出
return 0;
}
高精度减法的话思想差不多,遵循数位不够减时向前借一,这里的高精度减法不做代码展示
代码展示
#include
#include
int main(){
int i, j, l1, l2, k, a[2002], b[2002], s[4005] = {0};//
char a1[2001],b1[2001];
scanf("%s",a1);
scanf("%s",b1);
l1 = strlen(a1);
l2 = strlen(b1);
k = l1 + l2;//两位数乘两位数不会超过四位数,不会低于三位数
for(i = 1;i <= l1;i++)//将个位数对齐数组下标 一
a[i] = a1[l1 - i] - '0';
for(i = 1;i <= l2;i++)
b[i] = b1[l2 - i] - '0';
for(i = 1;i <= l1;i++){
for(j = 1;j <= l2;j++){
s[i + j - 1] += a[i] * b[j];//先将各个位数上的数对齐,相加并保存
}
}
for(i=1;i <= l1 + l2;i++){
if(s[i] > 9){
s[i + 1] += s[i] / 10;//让各个位数上的数字逢十进一
s[i] %= 10;
}
}
// k += 1 ;//数组第一个元素下标为0
for(i = k; k >= 1;i--){
if(s[k] == 0)
k--;
else
break;
}
if(k == 0)
printf("0");
else{
for(i = 1;i <= k;i++)
printf("%d",s[k - i + 1]);
}
return 0;
}
思想:高精度阶乘和就是高精度加法和高精度乘法的结合。
代码展示
#include
#include
#include
int main(){
int n, i, j, k = 100, a[101] = {0}, b[101] = {0};
scanf("%d",&n);
a[1] = b[1] = 1;
for(i = 2;i <= n;i++){
for(j = 1;j < 101;j++){
a[j] = a[j] * i;//计算各个位数的 阶乘 ,对应高精度乘法
b[j] += a[j];//计算各个位数的 阶乘和,对应高精度加法
}
for(j = 1;j < 101; j++){
a[j + 1] += a[j] / 10;//逢十进一
a[j] = a[j] % 10;
b[j + 1] += b[j] / 10;//逢十进一
b[j] %= 10;
}
}
for(i = 100;i >= 1;i--){
if(b[i] == 0)
k--;
else{
break;
}
}
for(i = k ;i >= 1;i--)
printf("%d",b[i]);
return 0;
}