大整数加法

   首先要对计算机原理的底层细节要清楚、要知道加减法的位运算原理和知道计算机中的算术运算会发生越界的情况,二是要具备一定的面向对象的设计思想。
      首先,计算机中用固定数量的几个字节来存储的数值,所以计算机中能够表示的数值是有定的范围的,为了便于讲解和理解,我们先以byte类型的整数为例,它用1个字节进行存储,表示的最大数值范围为-128到+127。-1在内存中对应的二进制数据为111111如果两个-1相加,不考虑Java运算时的类型提升,运算后会产生进位,二进制结果为1,11111110,由于进位后超过了byte类型的存储空间,所以进位部分被舍弃,即最终的结果为1111110,也就是-2,这正好利用溢位的方式实现了负数的运算。-128在内存中对应的二进制数据为10000000,如果两个-128相加,不考虑Java运算时的类型提升,运算后会产生进位,二进制结果为1,0000000由于进位后超过了byte类型的存储空间,所以进位部分被舍弃,即最终的结果为000000000也就是0,这样的结果显然不是我们期望的,这说明计算机中的算术运算是会发生越界情况的,两个数值的运算结果不能超过计算机中的该类型的数值范围。

    我们先在java中看一下以下实验输出的结果:
 

		int b1=Integer.MAX_VALUE;
		int b2=Integer.MAX_VALUE;
		System.out.println(b1+"+"+b2+"="+(b1+b2));

从运行程序可以看到结果为:2147483647+2147483647=-2,这显然不符合我们的目地,这就是计算机中算术发生越界的情况,为了实现大整数的加法,我们得从加法的基本法则入手。在我的代码中,输入的数据为字符串,这样可以保证输入的数据为任意长度的整数,然后将输入的字符串用byte类型的数组储存起来,无论你输入多大的数都可以,计算加法时逐次从byte数组的最后一位开始计算,这其中就有考虑到进位和两个byte数组的长度问题。实现了大整数加法的问题,大整数减法,乘法,除法也可以按照同样的方法进行计算,从算法的原理入手,不过这其中涉及的逻辑问题比较复杂。下面是实现大整数加法的结果与代码。

                          大整数加法结果截图

下面是具体代码实现

public class BigIntegerAdd {
 
	public static void main(String[] args) {
		// TODO Auto-generated method stub		
		BigIntegerAdd test5=new BigIntegerAdd();
		test5.BigNumAdd("111", "999");
		System.out.println();
		test5.BigNumAdd("111", "111");
		System.out.println();
		test5.BigNumAdd("1111111111191111", "3343425435345234545");
		System.out.println();
		test5.BigNumAdd("111111111134345111111", "3343423532965545234545");
	}
	/*
	 * 实现任意大数字(正整数)的加法
	 */
	public void BigNumAdd(String bignum1,String bignum2)
	{
		byte num1[]=null;
		byte num2[]=null;
		//将数组长度长的放在num1中
		if(bignum1.length()>bignum2.length())
		{
			num1=new byte[bignum1.length()];
			num2=new byte[bignum2.length()];
			for(int i=0;i<num1.length;i++)
				num1[i]=(byte) Integer.parseInt(bignum1.charAt(i)+"");
			for(int i=0;i<num2.length;i++)
				num2[i]=(byte) Integer.parseInt(bignum2.charAt(i)+"");
		}else{
			num1=new byte[bignum2.length()];
			num2=new byte[bignum1.length()];
			for(int i=0;i<num1.length;i++)
				num1[i]=(byte) Integer.parseInt(bignum2.charAt(i)+"");
			for(int i=0;i<num2.length;i++)
				num2[i]=(byte) Integer.parseInt(bignum1.charAt(i)+"");
		}
 
		//输出数组
		for(int i=0;i<num1.length;i++)
			System.out.print(num1[i]);
		System.out.println();
		for(int i=0;i<num2.length;i++)
			System.out.print(num2[i]);
		System.out.println();
		//获取两个数组的长度
		int length=num1.length>=num2.length?num1.length:num2.length;
		int minlength=num1.length<num2.length?num1.length:num2.length;
		boolean isCarry=false;//判断数字相加后是否进位
		
		byte result[]=new byte[length];//保存结果变量,如果计算后超出长度,
		//也就是说计算后最高位进位,在result长度增加1,并且最高位也是1
		for(int i=length-1,j=minlength-1;i>=0&&j>=0;i--,j--)
		{
			int r=num1[i]+num2[j];
			//如果相加大于等于10,进位
			if(isCarry)
			{
				r++;
			}			
			if(r>=10)
			{			
				isCarry=true;
			}else{
				isCarry=false;
			}
			result[i]=(byte) (r%10);
		}
		System.out.print(bignum1+"+"+bignum2+"=");
		if(length==minlength)//当两个数长度相等的情况
		{
			if(isCarry)
			{
				byte resultt[]=new byte[length+1];
				resultt[0]=1;
				for(int i=0;i<length;i++)
					resultt[i+1]=result[i];				
				for(int i=0;i<length+1;i++)
					System.out.print(resultt[i]);
				System.out.println();
			}else{
				for(int i=0;i<length;i++)
					System.out.print(result[i]);
				System.out.println();
			}
			return;
		}
		//当两个数长度不相等的情况
		if(num1.length>num2.length)
		{
			int dis=num1.length-num2.length;
			boolean resultisCarry=false;//最高是否再进以为,比如99进一位,变成100,数组长度改变
			if(isCarry)
			{
				boolean tempisCarry=false;//判断前一位进位1后是否继续进位,比如999这种情况
				for(int i=dis-1;i>=0;i--)
				{
					int r=num1[i]+1;
					if(r>=10)
					{
						tempisCarry=true;
					}else{
						tempisCarry=false;
					}
					result[i]=(byte) (r%10);
				}
				resultisCarry=tempisCarry;					
			}else{
				for(int i=dis-1;i>=0;i--)
					result[i]=num1[i];
			}
			//最高位进位,数组长度增加1,最高位必为1
			if(resultisCarry)
				System.out.print(1);
			for(int i=0;i<result.length;i++)
			{
				System.out.print(result[i]);
			}
			System.out.println();
		}
	}
 
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值