当我们需要写出一个程序算出两数乘积时会很容易写出如图所示的代码
从图中也可以看出这样的程序并不支持我们计算太大的数字 这是因为计算机内部直接使用int等数据类型储存数字是有范围限制的
当数据运算大小过大时 计算机将会出现溢出的情况 所以这时我们就需要高精度算法
所谓高精度算法就是使用数组 字符串完成对过大数字的运算和表达
而高精度乘法则是对我们在草稿纸上乘法运算的1:1还原
我将其分为 输入 拆分 乘算 进位 输出 五个部分
1>输入
char a[1500],b[1500];
scanf("%s%s",a,b);//以字符形式输入两个数字 不用&!
无需多言
2>拆分
eg: 1234*123--> 1 2 3 4
1 2 3
*
--------------
int x=strlen(a);
int y=strlen(b);
int m[x],n[y];//用来储存拆分出来的每一位数字
int i, j;//利用for循环结合ascii表将ab两数组的字符形式数字每一位拆分出来变成普通数字
for (i = 0, j = x - 1; i < x; i++, j--)
{
m[i] = a[j] - '0';
}
for (i = 0, j = y - 1; i < y; i++, j--)
{
n[i] = b[j] - '0';
}
3>乘算
eg: 1 2 3 4 --> 4*3 3*3 2*3 1*3
1 2 3 4*2 3*2 2*2 1*2
* 4*1 3*1 2*1 1*1
-----------
int c[3000];//数组c用来储存计算后的每一位数
for(i=0;i<3000;i++)//用for循环将c数组每一位填充成0
{
c[i]=0;
}
for (i = 0; i < x; i++)//将拆分后的数字进行乘法运算
{
for (j = 0; j < y; j++)
{
c[i + j] += m[i] * n[j];
}
}
4>进位
eg: 1 2 3 4 --> --> 1 2 3 4
1 2 3 1 2 3
* *
----------- -----------
3 7 0 2
2 4 6 8
1 2 3 4
-----------------
1 5 1 7 8 2
for (i = 0; i < x + y; i++)//处理进位
{
if (c[i] >= 10)
{
c[i + 1] += c[i] / 10;
c[i] %= 10;
}
}
5>输出
for (j = 2999; j > 0; j--)//确定最后一位数储存在哪个位置
{
if (c[j] != 0)
break;
}
for (i = j; i >= 0; i--)//根据得出的位置输出
{
printf("%d", c[i]);
}
最后 源代码
#include<stdio.h>
#include<string.h>
int main()
{
char a[1500],b[1500];
scanf("%s%s",a,b);//以字符形式输入两个数字 不用&!
int x=strlen(a);
int y=strlen(b);
int m[x],n[y];//用来储存拆分出来的每一位数字
int i, j;//利用for循环结合ascii表将ab两数组的字符形式数字每一位拆分出来变成普通数字
for (i = 0, j = x - 1; i < x; i++, j--)
{
m[i] = a[j] - '0';
}
for (i = 0, j = y - 1; i < y; i++, j--)
{
n[i] = b[j] - '0';
}
int c[3000];//c用来储存计算后的每一位数
for(i=0;i<3000;i++)//用for循环将c数组每一位填充成0
{
c[i]=0;
}
for (i = 0; i < x; i++)//将两个拆分后的数字进行乘法运算
{
for (j = 0; j < y; j++)
{
c[i + j] += m[i] * n[j];
}
}
for (i = 0; i < x + y; i++)//处理进位
{
if (c[i] >= 10)
{
c[i + 1] += c[i] / 10;
c[i] %= 10;
}
}
for (j = 2999; j > 0; j--)//确定最后一位数储存在哪个位置
{
if (c[j] != 0)
break;
}
for (i = j; i >= 0; i--)//根据得出的位置输出
{
printf("%d", c[i]);
}
return 0;
}