关于位运算加法对于负数也成立的我的理解

首先放上位运算实现加减乘除的java代码:
public static int add( int number_1, int number_2 )
	{
		int sum = 0;
		int carry = 0;
		do
		{
			sum = number_1 ^ number_2;
			carry = ( number_1 & number_2 ) << 1;
  
			number_1 = sum;
			number_2 = carry;
		} 
		while ( carry != 0 );
		return sum;
	}
	public static int minus(int a,int b)
	{
		return  add(a,add(~b,1));
	}
	public static int multip(int a,int b)
	{
		
		int absoluteB,product=0;;
		if(b<0)
		{
			absoluteB=add(~b,1);
			product=addGetMultip(product,a,absoluteB);
			product=add(~product,1);
		}
		else 
			{
			absoluteB=b;
			product=addGetMultip(product,a,absoluteB);
			}
		return product;
	}
	public static int division(int a,int b) throws ArithmeticException
	{
		if(b==0)
			throw new RuntimeException("除数不能为零!");
		int result=0;
		int absoluteA,absoluteB;
		if(a<0)
			absoluteA=add(~a,1);
		else absoluteA=a;
		if(b<0)
			absoluteB=add(~b,1);
		else absoluteB=b;
		int difference=absoluteA;
		while(difference>=absoluteB)//如果b==0,必须抛出异常,否则将无限循环下去
		{
			difference-=absoluteB;
			result++;
		}
		if((a>0&&b<0)||(a<0&&b>0))
			result=add(~result,1);
		
		return result;
	}
private static int addGetMultip(int product,int base,int time)
{
	int i=0;
	while(i<time)
	{
		product=add(product,base);
		i++;
	}
	return product;
}
}

以上位运算实现加法的代码我参考了网上的资源,然后减乘除则是依赖于加法自己实现的,可能有些不够精辟,但是能正常执行并得出结果。

接下来进入正题,对于加法运算的实现原理请参考:位运算实现加法的原理 

通过测试,该加法计算方法对于负数也能够完美实现,但是在计算机语言中负数是以补码的形式存放的,也就是说一个正数的相反数就是该正数的二进制形式取反加一。

例如:对于字节型的1,在内存中的存放形式是0000 0001,而-1则是1的反码(1111 1110)加上1,即1111 1111。对于这样形式的负数仍能以上面的实现原理来理解吗,

也许你能,反正我是不能。于是我就思考为什么负数也能通过此方法进行运算。最后得到如下结论:

首先,既然我无法理解负数为什么能够用此方法进行计算,那么我就不把负数当做一个负数,而把整个数当做一个没有负数标记位的正数。

然后,我们可以取一个数,然后将其取反,不难知道,将这个数和其反码相加的结果永远是全部为1,例如0011 0101与1100 1010加起来就是1111 1111。如果这个数据类型有n位,那么用它表示的一个整数和它的反码的和的值可以用2^n-1的形式二进制形式来表示,即a+~a=2^-1。而我们知道相反数数的表示形式其实是反码加一,所以对于一个数a,其相反数-a的表示形式就是:-a=(2^n-1-a)+1=2^n-a 。

接着,当我们把负数当做正数来看的话,对于两个整数a和b,我们假设它们的最高位都为0,即我们所认识的正数,那么a+b=add(a,b)。那么当我们要计算a的相反数和b的和的时候,我们可以先得到a的相反数的表现形式2^n-a,但是我们把它看做一个正数,然后调用该方法add(2^n-a,b) ,计算的结果本来应当是是2^n-a+b的二进制形式。

1.当b>a的时候该结果的值已经大于2^n-1,结果是向第n+1位进一,但是计算机是不会保存这个一的,因为该数据类型只有n位,于是得到的二进制表现形式其实是2^n-a+b-2^n即b-a的二进制表现形式,显然这个数就是-a和b的和的值。

2.当b<a的时候,计算的结果的确是2^n-a+b的二进制表现形式。这个时候我们要用到上面得到的结论:对于一个数a,其相反数的表现形式是2^n-a ,而此时我们用一个正数         (a-b)来代替这个a,于是得到其相反数(b-a)即-a+b的二进制表示形式2^n-(a-b)=2^n-a+b,这与我们用add方法计算出的二进制表现形式完全一致,因此,对于负数的运算,该方法也能完美执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值