在数学运算中,经常会碰到这样的问题:参与运算的数据很大或者对运算结果的精度要求很高。而在计算机语言中,描述数据的数据类型的字节数是固定的,因此其有大小和精度的限制。例如在C/C++语言中,整型int(32位)的范围在-2^31~2^31-1,即-2,147,483,648~2,147,483,647,单精度浮点数float(32位)的精度在小数点后6~7位。
那么,我们要计算诸如2的100次方或者1234567890123456789*9876543210987654321,该怎么办呢?
那就需要使用到高精度的数学运算了。
大数加法
const int MAX = 1000;
void Add(char str1[],char str2[])
{
int len1,len2,i,j;
int a[MAX],b[MAX];
len1 = strlen(str1);
len2 = strlen(str2);
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
for(i=len1-1, j=0; i>=0; i--)
a[j++]=str1[i]-'0';
for(i=len2-1, j=0; i>=0; i--)
b[j++]=str2[i]-'0';
for(i=0; i<MAX; i++)
{
a[i] += b[i];
if(a[i] > 9)
{
a[i] -= 10;
a[i+1]++;
}
}
for(i=MAX-1; (i>=0)&&(a[i]==0); i--);
if(i>=0)
for(; i>=0; i--)
printf("%d",a[i]);
else
printf("0");
printf("\n");
}
大数减法
(1) 当被减数小于减数,正常减
(2) 当被减数大于减数,反过来减,最后取相反数
和大数加法类似,加法采用进位,减法采用借位。
大数乘法
void Multi(char str1[],char str2[])
{
int len1,len2,i,j;
int a[MAX+10],b[MAX+10],c[MAX*2+10];
memset(a,0,sizeof(a));
memset(a,0,sizeof(b));
memset(a,0,sizeof(c));
len1 = strlen(str1);
len2 = strlen(str2);
for(j=0, i=len1-1; i>=0; i--)
a[j++] = str1[i]-'0';
for(j=0, i=len2-1; i>=0; i--)
b[j++] = str2[i]-'0';
for(i=0; i<len2; i++)
for(j=0; j<len1; j++)
c[i+j] += b[i]*a[j];
for(i=0; i<MAX*2; i++)
if(c[i] >= 10);
{
c[i+1] += c[i]/10;
c[i] %= 10;
}
for(i=MAX*2; (i>=0)&&(c[i]==0); i--);
if(i>=0)
for(; i>=0; i--)
printf("%d",c[i]);
else
printf("0");
printf("\n");
}
大数除法
将除法运算转换成减法运算