Q15二进制中1的个数

二进制简述

二进制运算

与或异或

与 & 或 | 异或 ^
0&0=0 0|0=0 0^0=0
0&1=0 0|1=1 0^1=1
1&0=0 1|0=1 1^0=1
1&1=1 1|1=1 1^1=0

左移

m<<n,表示把m左移n位。最左边的n位将被丢弃,右边补上n个0;

00001010<<2 = 00101000

10001010<<3 = 01010000

右移

m>>n,表示把m右移n位。右移的时候,右边的n位将被丢弃,左边补位的时候,要分情况。

  1. unsigned 无符号,补0
  2. signed,有符号,用符号位补。如果原来是正数,就补0,原来是负数,就补1.

00001010>>2 = 00000010

10001010>>3 = 11110001

补码的概念

在二进制码中,为了区分正负数,采用最高位是符号位的方法来区分,正数的符号位为0、负数的符号位为1.剩下的就是这个数的绝对值部分,可以采用原码、反码、补码3种形式来表示绝对值部分.
原码最简单,也最好理解.原码就是绝对值的二进制数形式:例如+7的8位二进制原码是00000111,-7的8位二进制原码是10000111.
但对于二进制运算而言,原码的运算不够方便,当两个数相加时,先要判断这两个数的符号是否相同,符号不同的话,还要判断哪一个数的绝对值更大.所以在计算机中,通常都是采用补码形式.

正整数的补码与原码形式相同,例如+7的8位二进制补码是00000111;

而负整数的补码则可以通过下列方式得到:

扫描二维码关注公众号,回复: 10650732 查看本文章

将这个负整数的绝对值求反加1,连同符号位1一起表示就可以了.

例如-7的8位二进制补码:将-7的绝对值7求反加1得1111001,连同符号位1一起就是11111001.
你也可以练习一下+13和-13的8位二进制补码:+13d=00001101,-13d=11110011. (按二进制看,是)

题目:二进制中1的个数

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

思路:

用一个flag,最低位先位1,然后用这个flag与整数做 与 操作,可得到 整数最低位是否为1,然后让flag左移1位,再与整数与操作,知道flag变0,记录与操作大于0的次数。

class Solution {
public:
     int  NumberOf1(int n) {
         unsigned int flag = 1;
         int count = 0;
         while(flag)
         {
             if(n&flag)
                 count++;
             flag=flag<<1;
         }
         return count;
     }
};

重要特点!!

把一个整数和它减去1的结果做 位与 运算,相当于把它最右边的1变成0。

class Solution {
public:
     int  NumberOf1(int n) {
         int count = 0;
         while(n)
         {
             ++count;
             n = n & (n-1);  //一个数与其减一的结果 位与,相当于把最右边的1变成0
         }
         return count;
     }
};

一个数字和自己做异或,会变成0。

思考题

  1. 用一条语句判断一个整数n是不是2的整数次方。

    一个数是2的整数次方的情况是,二进制中只有一个位是1,因此

    bool is2Multiple =(n&(n-1)==0);

  2. 输入两个整数m, n,计算需要改变m的二进制中多少位才能得到n。

    步骤1:对m 和 n求 异或,同0异1。1的个数就表示不同的位数

bool is2Multiple =(n&(n-1)==0);

  1. 输入两个整数m, n,计算需要改变m的二进制中多少位才能得到n。

    步骤1:对m 和 n求 异或,同0异1。1的个数就表示不同的位数

    步骤2:统计 异或结果中 1的位数。

发布了48 篇原创文章 · 获赞 10 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/mhywoniu/article/details/104933072