不用四则运算符计算加减乘除法

这个牵扯到计算机的计算原理。都知道计算机都是以二进制来存储的,所二进制的加减乘除可以看成是 异或,移位来运算得到。

 

package Opera;

/**
 * 不用 "+ , - , * , /"进行四则运算
 * 
 * @author Administrator
 *
 */
public class FourOPera {

	public static void main(String[] args) throws Exception {

		System.out.println(add(5, 17));// 正负数 都适用

		System.out.println(add(-5, -17));
		
		System.out.println(by(14097, 56));
		
		System.out.println(_by(14097, 56));
		
		System.out.println(divide(789456, -56));
	}

	/**
	 * 1、模拟加法,先进行不进位加法 2、在进行进位计算 3、将结果相加(这里是二级制结果)<br>
	 * 
	 * 对于二进制相加其实就是 异或( 1 + 1 = 0, 1 + 0 = 1, 0 + 1 = 1) --> a ^ b <br>
	 * eg: 5 + 17 => 101 + 10001; <br>
	 * a ^ b => 10100 => 4 + 16 = 20; <br>
	 * a & b << 1 = > 00001 << 1 => 00010 => 2<br>
	 * 20 + 2 = 22;<br>
	 * 
	 * @param a
	 * @param b
	 * @return
	 */
	public static int add(int a, int b) {
		int sum = 0, carry = 0;
		while (b != 0) {
			sum = a ^ b;
			carry = (a & b) << 1;
			a = sum;
			b = carry;
		}
		return sum;
	}

	/**
	 * 计算乘法 比如 5 * 3 实际上就是 5 + 5 + 5。<br>
	 * 貌似就说完了。实际上不仅仅如此的。现在有一个电子器件叫做乘法器,其可以实现二进制的乘法、除法等运算。我们同样以 5 * 3<br>
	 * 做为例子,讲解一下乘法器计算乘法的流程。<br>
	 * 
	 * 5 * 3 = 0000 0101 * 0000 0011 <br>
	 * 3 的第 0 位为 1 ,那么 5 左移 0 位,结果为 0000 0101 ; <br>
	 * 3 的第 1 位为 1 ,那么 5 左移 1 位,结果为 0000 1010 ; <br>
	 * 3 的其他高位都为 0 ,因此不再左移; 两次左移的结果累加,<br>
	 * 即 0000 0101 + 0000 1010 = 0000 1111 ,即十进制的 15 。<br>
	 * 
	 * @param a
	 * @param b
	 * @return
	 * @throws Exception 
	 */
	public static int by(int a, int b) {
		if(a == 0 || b == 0) {
			return 0;
		}
		boolean isAf = false;
		boolean isBf = false;
		if(a < 0) {
			a = -a;
			isAf = true;
		}
		if(b < 0) {
			b = -b;
			isBf = true;
		}
		int brr[] = new int[32];
		int result[] = new int[32];
		// 取到二进制
		int i = 32;
		while (i-- > 0) {
			brr[31 - i] = b >> i & 1;
		}
		int index = 0;
		for (int j = 31; j > 0; j--) {
			if (brr[j] >= 1) {
				result[index++] = a << (31 - j);
			}
		}

		int r = 0;
		for (int j = 0; j < 32; j++) {
			r += result[j];
		}
		if(!isAf && !isBf || isAf && isBf) {
			return r;
		}else {
			return -r;
		}
		
	}
	
	/**
	 * 当然 乘法其实还可以看成 加法运算,所以也可以这样计算<br>
	 * 
	 * 3 * 5 => 00011 * 00101<br>
	 * 其实也是移位
	 * @param a
	 * @param b
	 * @return
	 */
	public static int _by(int a, int b) {
		int ans = 0;
		int index = 0;
		
		while(b != 0) {
			if((b & 1) == 1) {
				ans = add(ans , a << index);
			}
			index = add(index, 1);
			b = b >> 1;
		}
		return ans;
	}
	
	/**
	 * 模拟除法 运算,结果保留整数位<br>
	 * 其实就是不断的减去除数<br>
	 * @param a
	 * @param b
	 * @return
	 */
	public static int divide(int a, int b) {
		int ans = 0;
		int result = 0;
		
		if(a == 0) {
			return 0;
		}
		if(b == 1) {
			return a;
		}
		if(b == - 1) {
			return - a;
		}
		boolean isAf = false;
		boolean isBf = false;
		if(a < 0) {
			a = -a;
			isAf = true;
		}
		if(b < 0) {
			b = -b;
			isBf = true;
		}
		
		while(a >= b) {
			ans = add(a , - b);
			a = ans;
			result ++;
		}
		if(!isAf && !isBf || isAf && isBf) {
			return result;
		}else {
			return - result;
		}
	}
	
}

运行结果:

22
-22
789432
789432
-14097
 

当然上面运算是有条件限制的,都是在int范围,且结果也是在int范围。假如加入小数运算,目前还不能满足。但是仔细一想。小时候我们学小数运算的时候。也是把小数当整数来计算,然后在把小数位加上去。归根结底其实还是四则运算原理。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值