C语言高精度乘法

前言

菜鸟的学习笔记,在之前就有做过高精度的乘法运算以及高精度阶乘运算,现在再写一遍加深一下印象。有错指出,虚心接受。


一、思考如何实现高精度乘法

因为C语言中无法直接计算很大的数字,所以另辟蹊径,用数组存储大数字,然后一位一位进行计算,就像用笔计算一样。这是大致的思考方向,接下来就用代码来实现。

二、代码实现

1.设置好需要的数组和一些变量

这里我们用a和b数组来存储需要计算的两个大数字,因为在C语言中字符数组可以直接输入字符串进去,如果用数字数组的话就需要一位一位去输入,很麻烦。但是这样存进去的数字是字符形式的,所以用第三块代码来转换为数字并存储到num1和num2数字数组中,并从最后一个位置存方便计算。

	int num1[1000]={0},num2[1000]={0},num[1000]={0},sum[1000]={0};
	char a[1000]={0},b[1000]={0}; 
	
	scanf("%s%s",a,b);
	int l1=strlen(a);
	int l2=strlen(b);
	
	int i=0;
	for(;i<l1;i++)
	num1[999-i]=a[l1-1-i]-'0';
	for(i=0;i<l2;i++)
	num2[999-i]=b[l2-1-i]-'0';

2.正题,计算

假设计算23*56,先用3去一位一位乘以56中的每一位数,并将其相加到sum数组中,然后再计算2去乘以56中的每一位数,再加到sum中,类推。
但我们发现,3乘完之后相加是168存在num数组中也是,sum数组中也是。用2去乘56得到是112,存到num中是112,在sum中相加是168+112,但答案是错的。
在纸上写一遍就可以发现问题所在了,实际上是要加1120的。而解决方法就是num[999-k-j],因为num所有元素都是0,只需要在j个0前存储就行了,所以-j就可以解决这个问题。

	int j,k,t1=0,t2=0;
	for(j=0;j<l1;j++)
	{
		t1=0,t2=0;
		for(k=0;k<l2+1+j;k++)  //相乘时,进位最多往前进一位,所以k<l2+1,而+j是为了相加而设置的,因为每次相加的数最后都会比前面多0而导致可能会多一位,这不会影响乘法的计算,因为num1和num2都已经是0了。
		{
			num[999-k-j]=num1[999-j]*num2[999-k]+t1;  //位相乘+进位来的数
			t1=num[999-k-j]/10;        //处理进位
			num[999-k-j]=num[999-k-j]%10;
			
			sum[999-k]=num[999-k]+sum[999-k]+t2;  //相当于高精度加法,差不多的意思。
			t2=sum[999-k]/10;
			sum[999-k]=sum[999-k]%10;	
		}
		memset(num, 0, sizeof(num));  //将num数组清0
	}

3.输出

因为我们的数都是从最后面开始存的,且前面都是0,所以可以判断是否第一次遇到非0来进行输出。

	i=0;
	while(sum[i]==0)
	i++;
	
	for(;i<1000;i++)
	printf("%d",sum[i]);

贴一下完整的代码

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
	int num1[1000]={0},num2[1000]={0},num[1000]={0},sum[1000]={0};
	char a[1000]={0},b[1000]={0}; 
	
	scanf("%s%s",a,b);
	int l1=strlen(a);
	int l2=strlen(b);
	
	int i=0;
	
	for(;i<l1;i++)
	num1[999-i]=a[l1-1-i]-'0';
	for(i=0;i<l2;i++)
	num2[999-i]=b[l2-1-i]-'0';
	
	int j,k,t1=0,t2=0;
	for(j=0;j<l1;j++)
	{
		t1=0,t2=0;
		for(k=0;k<l2+1+j;k++)
		{
			num[999-k-j]=num1[999-j]*num2[999-k]+t1;
			t1=num[999-k-j]/10;
			num[999-k-j]=num[999-k-j]%10;
			
			sum[999-k]=num[999-k]+sum[999-k]+t2;
			t2=sum[999-k]/10;
			sum[999-k]=sum[999-k]%10;	
		}
		memset(num, 0, sizeof(num));
	}
	
	i=0;
	while(sum[i]==0)
	i++;
	
	for(;i<1000;i++)
	printf("%d",sum[i]);
}

总结

主要是知道乘法在纸上运算的方法就行,在处理好一些细节就行。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值