二进制中1的个数

题目描述

输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

思路

1)自然而然的思路:二进制数最后一位和1与运算,是1返回1,是0返回0;然后,右移一位【负数会引起死循环】
但是,在计算机中负数以补码存储时,符号位为1,右移最高位补1,最后会死循环(0xFFFFFFFF)
解决办法有2:

  • 将二进制数转换成无符号数
  • Java中有逻辑(无符号)右移操作符>>>,只对位进行操作,没有算术含义,它用0填充左侧的空位

算术右移不改变原数的符号,高位补符号位,而逻辑右移不能保证这点(负数会改变原数的符号)

2)逆向思维:将使用按位与运算判断原数某位是否为1的操作数左移,按位逐次比较
3)惊喜:(原数-1)& 原数,原数最后一位1变为0

总结:

  • Java中没有unsigned
  • Java中Int类型占4B(32b)

代码:

1)逻辑右移运算符>>>

public static int numberOf1(int n){
		
		int count = 0;
		
		while(n != 0){
			if((n & 1) == 1)
				count++;
			n = n >>> 1;
		}
		return count;
	}

2)与运算操作数左移

public static int numberOf1New(int n){
		int count = 0;
		int flag = 1;
		
		//使用flag作为循环标志,移动32次之后,变成0(左移补0)
		while(flag != 0){
			//判断条件不能是 == 1
			if((n & flag) != 0){

				count++;
			}
			
			flag = flag << 1;
		}
		
		return count;
	}

3)自操作

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

posted @ 2017-04-23 22:48  gleesu  阅读(231)  评论(2编辑  收藏  举报