【算法章】高精度乘法(精讲)

1.为什么需要高精度:

        我们常用的“int”类型通常占用 4 个字节(即 32 位),其数据范围为:-2147483648 到2147483647。而“long long”的范围是 -9223372036854775808 到 9223372036854775807。也就是说,当数据过长时,我们便需要用到高精度算法解决问题。相信前来学习高精度的同学也都遇到了相应问题,这里不再赘述了。

2.高精度乘法的基本逻辑:

  1.  对于过长的数据,我们采用数组的形式来处理。
  2. 将每一位数字相乘(抛开我们惯用让乘数的每一位与另一个乘数相乘的思想,仔细理解一下这种思想,其实是一样的)。
  3. 最后处理进位,输出结果即可。

3.高精度乘法逐步剖析讲解:

(1)我们引入两组数字

char m[2000],n[2000];
scanf("%s",&m);
scanf("%s",&n);

    用char的原因:

        (1)我们在后面要使用strlen函数去获取字符串长度(不理解欢迎评论区提问)。

        (2)方便输入。

(2)将每一位“char”型数字逆序存放进整型数组

int a[2000]={0},b[2000]={0};
int lm,ln;//lm、ln分别表示m和n的位数
lm=strlen(m);//strlen函数是获取数组长度的,如abc的长度为3
ln=strlen(n);
for(i=0;i

(3)计算并处理进位


int i,j,k;
for(i=0;i=10)//保证数组中的数字都<10
			{
				c[k+1]+=c[k]/10;//c[i+1]进c[i]的十位
				c[k]%=10;//保留c[i]的个位
			}
		}
	}

(4)确定积的位数

   乘法结果位数的三种情况:

  1. 位数等于两乘数位数之和(如9 *9=81)。
  2. 位数等于两位数的和减1(如1*9=9)。
  3. 结果为0(100*0=0)。
int lm,ln,lc;//lc表示乘积c的位数
if(c[lm+ln-1]!=0)//情况1
    {
		lc=lm+ln;
	}
	else//情况2
	{
		lc=lm+ln-1;
	}
while(c[lc-1]==0&&lc>1)//情况3
	{
		lc--;//这里我用的是清除前导0,比较字符串的方法也是可以的
	}

(5)逆序输出积

for(i=lc-1;i>=0;i--)
	{
		printf("%d",c[i]);
	}

为什么逆序输出不必我说了吧,本来数组里的数就是反着的,输出时候肯定也要反过来啊。

4.完整代码

#include
#include
main()
{
	char m[2000],n[2000];
	int a[2000]={0},b[2000]={0},c[4000]={0};
	int i,j,k;
	int lm,ln,lc;
	scanf("%s",&m);
	scanf("%s",&n);
	lm=strlen(m);
	ln=strlen(n);
	for(i=0;i=10)
			{
				c[k+1]+=c[k]/10;
				c[k]%=10;
			}
		}
	}
	if(c[lm+ln-1]!=0)
	{
		lc=lm+ln;
	}
	else
	{
		lc=lm+ln-1;
	}
	while(c[lc-1]==0&&lc>1)
	{
		lc--;
	}
	for(i=lc-1;i>=0;i--)
	{
		printf("%d",c[i]);
	}
}

————(如有问题,欢迎评论区提问)————

你可能感兴趣的:(算法,算法,c语言)