用java数组展示计算机的多位数相乘

用java数组展示计算机的多位数相乘

我们通常用java语言实现多位数相乘时,都是直接输入两个数然后便会输出结果
例如:System.out.print(1234*567);
便直接得到结果: 699678

那计算机里面是怎么实现多位数相乘的呢?

换句话说,计算机不可能储存每个数相乘的结果。和我们计算乘法一样——我们用所背乘法口诀表来计算。计算机只记录了乘法表的结果,然后以此为基础计算所有多少位数相乘的结果。
例:
这里3*4=12  需要向高位进一位
下面我们用java数组展示下用这个原理来计算多位数:
1、引进两个乘数并放入数组中


		//因为int类型的整数最大范围为2147483647
		//而使用字符串类型即String可以计算长度更大的多位数,所以这里不直接用int类型
		String sa="12345";//乘数sa
		String sb="678";//乘数sb
		int i,j,carry=0;//carry用于暂时存储两数相乘时的进位
		//将字符串切割为一个个char字符,并转换为整形放入整形数组里
		int Array_a[]=new int[sa.length()];
		int Array_b[]=new int[sb.length()];
		for(i=0;i<sa.length();i++)
			Array_a[Array_a.length-1-i]=Integer.parseInt(sa.charAt(i)+"");
		for(i=0;i<sb.length();i++)
			Array_b[Array_b.length-1-i]=Integer.parseInt(sb.charAt(i)+"");
			
	

注:这里我们存放整形数组时,是将字符串逆序存放,
即Array_a数组存放的是 54321
Array_b数组存放的是 876
因为后面这两个数组元素计算相乘时的进位逆序更容易添加。

2、创建一个二维数组,用于存放两个数组相乘的结果

int c[][]=new int[Array_b.length+1][Array_a.length+Array_b.length];

注:
二维数组c[][]行数为Array_b.length+1创多一行,因为用最后一行储存相加的结果
二维数组c[][]列数为Array_a.length+Array_b.length,因为两数相乘的结果的位数不可能大于这两个数的位数之和。
(即999=891 结果不可能大于三位数——即99和9两个数的位数和
同理999
99=98901 结果不可能大于五位数——即999和99两个数的位数和

3、计算两个数组的相乘

	for(i=0;i<Array_b.length;i++)
		{
			for(j=0;j<Array_a.length;j++)
			{
			    //carry为进位 前面代码中已经创建并赋值为零  carry=0
				c[i][j]=(carry+Array_b[i]*Array_a[j])%10;//进位和所乘的结果相加并求余
				carry=(carry+Array_b[i]*Array_a[j])/10;//下一个高位数的进位
				if(j==Array_a.length-1)//当最后一位数仍然要进位时,最后一个数直接等于进位
					c[i][Array_a.length]=carry;
			}
			carry=0;//重置进位为0
		}

为方便理解 概念图如下:
在这里插入图片描述
注:下面的箭头表示进位的数为多少例8*5=40向高位进4
上述代码计算完后结果为:
在这里插入图片描述

下一步:

//对所得结果的数组进行数组移位(即等于两数相乘时十位数往后添1个0,百位数往后添2个0等)
		for(i=1;i<c.length;i++)
			move_array(c[i],i);

下面是自己写的移位函数(具体怎么样不细讲):

//一维数组移位函数
	public static void move_array(int a[],int leng)
	{
		int i;
		int b[]=new int[leng];
		for(i=0;i<b.length;i++)
			b[i]=a[a.length-1-i];
		for(i=a.length-1;i>=leng;i--)
			a[i]=a[i-leng];
		for(i=0;i<b.length;i++)
			a[i]=b[b.length-1-i];
	}

因为个位数乘完之后到十位数相乘并且需要移到十位数上面相乘
即:
在这里插入图片描述
移位后相加:

//用上述移位后的二维数组相加并储存到最后一行的二维数组中
		for(j=0;j<Array_a.length+Array_b.length;j++)
		{
			for(i=0;i<Array_b.length;i++)
			{
				c[Array_b.length][j]=c[Array_b.length][j]+c[i][j];//数组每列累加到每列最后一个数
				if(i==Array_b.length-1)
				{
					int c1=c[Array_b.length][j];//用于存储累加前的元素
					c[Array_b.length][j]=(carry+c[Array_b.length][j])%10;
					carry=(carry+c1)/10;
				}
			}
		}

概念图如下:
在这里插入图片描述
4、最后将结果逆序并转为字符串输出结果:

//转换为字符串
		String result="";
		int judge=0;//用于判断数组移去前面的0后不再移动后面的0
		for(j=Array_a.length+Array_b.length-1;j>=0;j--)
		{
			if(c[Array_b.length][j]!=0||judge==1)
			{
				result=result+c[Array_b.length][j];
				judge=1;
			}
		}
		System.out.println(result);

完整代码如下:

public class 多位数相乘 {
	public static void main(String[] args)
	{
		int a=12345,b=678;
		System.out.println("计算结果:"+multiply(a, b));
		System.out.println(a+"*"+b+"="+(a*b));
	}
	
	public static String multiply(int a,int b)
	{
		//将整数a,b转换为字符串,确定 Array_a[]和Array_b[]数组长度,
		//并再次转换为整型存到 Array_a[]和Array_b[]数组中
		String sa=""+a;
		String sb=""+b;
		int i,j,carry=0;//carry用于暂时存储两数相乘时的进位
		int Array_a[]=new int[sa.length()];
		int Array_b[]=new int[sb.length()];
		for(i=0;i<sa.length();i++)
			Array_a[Array_a.length-1-i]=Integer.parseInt(sa.charAt(i)+"");
		for(i=0;i<sb.length();i++)
			Array_b[Array_b.length-1-i]=Integer.parseInt(sb.charAt(i)+"");
		//创建二维数组,用于储存 Array_a[]和Array_b[]每个元素相乘的结果
		//二维数组行数为Array_b.length+1创多一行,因为用最后一行储存相加的结果
		//二维数组列数为Array_a.length+Array_b.length,因为两数相乘的结果的位数不可能大于这两个数的位数之和
		int c[][]=new int[Array_b.length+1][Array_a.length+Array_b.length];
		
		//计算 Array_a[]和Array_b[]每个元素相乘的结果并储存
		for(i=0;i<Array_b.length;i++)
		{
			for(j=0;j<Array_a.length;j++)
			{
				c[i][j]=(carry+Array_b[i]*Array_a[j])%10;
				carry=(carry+Array_b[i]*Array_a[j])/10;
				if(j==Array_a.length-1)
					c[i][Array_a.length]=carry;
			}
			carry=0;
		}
		//对所得结果的数组进行数组移位(即等于两数相乘时十位数往后添1个0,百位数往后添2个0等)
		for(i=1;i<c.length;i++)
			move_array(c[i],i);
		//用上述移位后的二维数组相加并储存到最后一行的二维数组中
		for(j=0;j<Array_a.length+Array_b.length;j++)
		{
			for(i=0;i<Array_b.length;i++)
			{
				c[Array_b.length][j]=c[Array_b.length][j]+c[i][j];//数组每列累加到每列最后一个数
				if(i==Array_b.length-1)
				{
					int c1=c[Array_b.length][j];//用于存储累加前的元素
					c[Array_b.length][j]=(carry+c[Array_b.length][j])%10;
					carry=(carry+c1)/10;
				}
			}
		}
		//转换为字符串
		String result="";
		int judge=0;//用于判断数组移去前面的0后不再移动后面的0
		for(j=Array_a.length+Array_b.length-1;j>=0;j--)
		{
			if(c[Array_b.length][j]!=0||judge==1)
			{
				result=result+c[Array_b.length][j];
				judge=1;
			}
		}
		return result;
		
	}
	//一维数组移位函数
	public static void move_array(int a[],int leng)
	{
		int i;
		int b[]=new int[leng];
		for(i=0;i<b.length;i++)
			b[i]=a[a.length-1-i];
		for(i=a.length-1;i>=leng;i--)
			a[i]=a[i-leng];
		for(i=0;i<b.length;i++)
			a[i]=b[b.length-1-i];
	}
}

这是运行结果:
在这里插入图片描述
我们也同样可以用这个计算 结果比int类型范围更大的数
在这里插入图片描述

在这里插入图片描述
下面结果已经12345678*22345的结果已经超过了int类型 所以结果是错误的

以上便是我用java数组展示计算机计算多位数相乘的原理
以上仅是我个人(代码菜鸟一枚)的理解看法,如有不当请各位大佬提出!谢谢!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值