逻辑运算符操作二进制位

加法运算

问题:不使用+、-、*、/来完成加法运算。
解法:

public int Add(int num1,int num2) {
    while (num2 != 0) {
           int temp = num1 ^ num2;
           int tmp = (num1 & num2) << 1;
           num1 = temp;
           num2 = tmp;
        }
    return num1;
}

原理:
num1 ^ num2:通过异或(^)运算得到的是在忽略进位情况下,得到的结果。

(num1 & num2) << 1:与运算(&)得到的是将会产生进位的位,通过向左移位一位得到被异或运算忽略的进位。

然后,再次进行异或运算将进位加到未进位的异或结果上,在这个异或过程中又会产生新的进位并重复这个过程。

实际上,你可以将把进位加到未进位的异或运算看做一次新的加法运算。

当在异或过程中不再产生新的进位时,num2将会变为0并结束循环,得到结果。

num1 = 15 	num2 = 3
(1111 +	0011) = 10010
	1111		1111
 ^	0011	  &	0011
----------	----------
	1100		0011	---左移1---> 0110
此时,(自右向左看)产生进位的是1位和2位,需要进位到2位和3位去;观察左移一位后1的位置正好是2位和3位。
重复操作
	1100		1100
 ^	0110	  &	0110
----------	----------
	1010		0100	---左移一位---> 1000
此时,产生进位的是3位,需要进位到4位去;观察左移一位后1的位置正好是4位。
重复操作
	1010		1010
 ^	1000	  &	1000
---------	----------
	0010		1000	---左移一位---> 10000
此时,产生进位的是4位,需要进位到5位去;观察左移一位后1的位置正好是5位。
重复操作
	00010		00010
 ^	10000	  &	10000
-----------	 ----------
	10010		00000
至此,得到正确结果(10010 = 18)并且num2变为0退出循环。

统计一个整数的二进制串中1的个数

解法:

public int NumberOf1(int n) {
       int count = 0;
       while (n != 0) {
           count++;
           n = n & (n - 1);
       }
       return count;
}

原理:
count:用于计数1的个数。

n & (n - 1):当一个二进制数减去1时,从右向左看将会使得第一个1变为0。此时将该数减一与该数进行与运算(&)后,因为与运算的特性,该数将保证第一个1被减后其后面一位依旧为0。该数减一将会保证该数第一个1之前的位不会被影响。

此时完成从右向左的第一个1去除,同时原本为0的位依旧为0.

n = 51 = 110011
n - 1  = 110010
	110011
  &	110010
------------
	110010		count = 1
此时,第一个1被置为0
n = 110010
n - 1 = 110001
	110010
  &	110001
------------
	110000		count = 2
此时,第二个1被置为0
n = 110000
n - 1 = 101111
	110000
  &	101111
------------
	100000		count = 3
此时,第三个1被置为0
n = 100000
n - 1 = 011111
	100000
  &	011111
------------
	000000		count = 4
此时,第四个1被置为0
n变为0,退出循环,从count处得到结果(110011 <---> 4)

END

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值