在机器中,整数的存储和运算都是其补码表示的。

  • 正数右移:保持为正数,相当于/2。

  • 负数右移:保持为负数,移位前是负数,移位后保持是负数,因此移位后最高位设为1。如果一直右移,最终会变成-1,即(-1)>>1是-1。

  • 正数左移:不保持为正数,相当于*2。(注意:1左移31时为负数最大值)

  • 负数左移:不保持为负数,在左移的过程中会有正有负的情况。所以切记负数左移不会特殊处理符号位。如果一直左移,最终会变成0。

<以上为个人总结,如有不对,望指正>

// 一般思路:负数右移问题,以前都是正数右移,采坑了

public class Solution {
    public int NumberOf1(int n) {
        int num = 0, flag = 1;
        while (flag != 0) {
            if ((n & flag) != 0) {
                num++;
            }
            flag <<= 1;
        }
        return num;
    }
}

// 独特思路:整数n,进行n&(n-1)运算,会把二进制表示中最右边的1变为0。(让我想起来树状数组中的lowbit函数,同样很神奇的位运算)

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