Number of 1 Bits (求32位二进制数中1的)

<span style="font-size:24px;">
</span>

1.题目:

Write a function that takes an unsigned integer and returns the number of ’1‘ bits it has (also known as the Hamming
weight
).

For example, the 32-bit integer ’11‘ has binary representation 00000000000000000000000000001011,
so the function should return 3.

2.熟悉位运算:

1、&(按位与) 从概念上来讲,就是将参与运算的两个分量对应的每一位来做逻辑与运算,若两者都为真(等于1),则结果才为真(等于1)。否则都为假(等于0)。

即:1 & 1 = 1 、1&0 = 0 、0&1 = 0、0&0 = 0

这里我们先来看看那一个8位二进制的例子:

7&8 = 0000 0111 & 0000 1000 = 0000 0000 = 0

7&6 = 0000 0111 & 0000 0110 = 0000 0110 = 6

2、| (按位或) 即把参与运算的每个分量对应的每一位来做逻辑或运算,即两者都为假(为0)时,才为假(为0),否则皆为真。

即:0|0 = 0、1|0 = 1、0|1 = 1、1|1 = 1

来看看8位二进制的例子:

7|8 = 0000 0111 | 0000 1000 = 0000 1111 = 15

7|6 = 0000 0111 | 0000 0110 = 0000 0111 = 7

3、^(按位异或) 即把参与运算的每个分量对应的每一位来做异或运算,即两者相同为假,不同为真。

即:0|0 = 0、 1|0 = 1、0|1 = 1、 1|1 = 0

看下面的例子:

7^8 = 0000 0111 ^ 0000 1000 = 0000 0111 = 7

7^6 = 0000 0111 ^ 0000 0100 = 0000 0011 = 3

4、~(按位取反) 即把二进制位的每一位进行取反运算,简而言之就是1变成0,0变成1。

直接看例子:

~7 = ~0000 0111 = 1111 1000 = 248

5 >>(按位右移)把二进制位整体向右移动。

7>>1 = 0000 0111 >> 1 = 0000 0011 = 3

7>>2 = 0000 0111 >> 2 = 0000 0001 = 1

这里右移等于除了2的N次方,N为右移的位数。

6 <<(按位左移)这里就不详细说了,和右移相反。

3.了解uint8_t,uint16_t,uint32_t等

  • a.uint8_t,uint16_t,uint32_t等都不是什么新的数据类型,它们只是使用typedef给类型起的别名。
  • 利用预编译和typedef可以让你最有效的维护你的代码。为了用户的方便,C99标准的C语言硬件为我们定义了这些类型,我们放心使用就可以了。

    按照posix标准,一般整形对应的*_t类型为:

    1字节     uint8_t

    2字节     uint16_t

    4字节     uint32_t

    8字节     uint64_t

  • 使用头文件要包含<stdint.h>(C99标准,VC6 不支持)

4.算法:

  • 最简单粗暴法:就是将二进制数与1与运算,判断最后一位是不是1,然后右移一位,直到数字移动完。
<span style="font-size:24px;">int hammingWeight(uint32_t n)
{
	int weight = 0;
	while (n)
	{
		if ((n & 1) == 1)
		{
			weight++;
		}
		n = n >> 1;
	}
	return weight;
}</span>

算法说明:容易想到,但是效率较低

  • 改进:上个算法的效率低的原因是每位都要比较,当有例如0x10000000时,明明就一个1,难道也要比较那么多次?

所以我们就只想找到非零的位进行比较: 利用n&(n - 1)每次迭代总是将最右边的非零位置零,这样就可以提高效率

<span style="font-size:24px;">int sparse_popcnt(unsigned int n)
{
	int count = 0;
	while (n)
	{
		++count;
		n &= (n - 1);
	}
	return count;
}</span>
  • 其他算法可以看这里的大神总结

5.具体实现可能遇到的问题:

  • 如何输出十进制,八进制,十六进制数字

     cout<<"DEC:"<<dec<<n<<endl;  //十进制
     cout<<"OCT:"<<oct<<n<<endl;//八进制
     cout<<"HEX:"<<hex<<n<<endl;//十六进制  

    注意:使用完某种方法比如十六进制后,要撤销,否则以后都按照十六进制输出

    cout << hex<<n << endl;
    cout.unsetf(ios::hex);

  • C++中无法表达二进制数,所以不要试图写个32位长的二进制数,让它认。。。。,用十六进制吧
  • VS调试的时候你想看16进制的值时候,在值右键->选择十六进制
时间: 2024-10-10 06:14:50

Number of 1 Bits (求32位二进制数中1的)的相关文章

PHP长整型在32位系统中强制转化溢出

CleverCode近期遇到一个PHP项目整形转化问题,mysql有一个字段id是bigint的,里面有长整型,如id = 5147486396.可是php代码因为历史原因却部署在多台机器中,当中A机器32位系统中,B机器64系统中.如今的问题是64系统中页面訪问正常.32位系统中訪问出错了.原因是php整形溢出. 1 A机器演示 1.1 获取A机器系统位数 # getconf LONG_BIT 1.2 整形转化代码 <? php $id = 5147486396; echo '$id:'.$i

4GB的内存条在32位系统中只能显示为3GB左右的原因(转)

原帖地址:http://bbs.51cto.com/viewthread.php?tid=875012&extra=&page=1 1. 4GB的内存条在32位系统中只能显示为3GB左右的原因 第一个原因只会“吃掉”您一小部分的内存 众所周知,电脑中二进制中的换算关系是 1GB=1024MB,实际生产时,硬件厂商厂商的换算单位是1GB=1000MB,当电脑厂商告诉您,您电脑中的内存是1GB的时候,其实您的内存是1000MB,系统识别时,用1000处以1024,也就显示您的内存是0.976G

将float类型中的32位二进制数用union表示出来

用十六进制表示出来的代码,考虑到联合体的一些特性.计算机组成原理中反码补码原码的特性浮点数表示的IEEE754标准.对于32位,S(符号位(1)),E(阶码位(8)),M(尾数(23)).对于64位,S(符号位(1)),E(阶码位11)),M(尾数(52)).计算方法,符号位,0正1负.阶码位,计算出值减去127为真正的阶码(小数点在数据中的位置).尾数不操作.如:0 10000010 10010000000000000000000,step1.0->整数step2.10000010 ,算得为1

为什么一个指针在32位系统中占4个字节,在64位系统中占8个字节?

一个指针在64位的计算机上,占8个字节:一个指针在32位的计算机上,占4个字节. 原因如下: 我们都知道cpu是无法直接在硬盘上读取数据的,而是通过内存读取.cpu通过地址总线.数据总线.控制总线三条线对内存中的数据进行传输和操作. 具体流程: 1.cpu通过地址总线,找到该条数据: 2.通过控制总线得知该操作是读操作还是写操作: 3.通过数据总线将该数据读取到cpu或者从cpu写到内存中. 所以, 地址总线的宽度决定了CPU的寻址能力: 数据总线的宽度决定了CPU单次数据传输的传送量,也就是数

C++获取Windows7 32位系统中所有进程名(类似于任务管理器中的进程)

代码是网上查找资料,然后自己调试,修改之后可以运行. 系统:win7 32位,VS2008 -----------------------------------------------------------------------代码------------------------------------------------------------------------------------ 1 #include <iostream> 2 #include <string&g

在32位系统中,int类型的最大值是多少?

首先分析一个问题:int类型一般情况下是否等于signed int类型,目前所知道的编译器一般是这样子的.那再问:为甚答案是2的31次方,减去1,原来符号整型的最大值是31个1,意味着是2^0+2^1+2^1+........+2^30,所以答案就是这个. 延伸出一个问题:如何得知windows的操作系统类型,打开控制面板,就可以看到操作系统类型,显示的是32位操作系统,在这里可以知道一个指针,是4个字节长度.曾经遇到float和double之间的区别,在实际的项目中,从来没有使用到float或

Visual Studio2015 (VS2015)简体中文版 安装教程(在Win 8.1 32位系统中)

VS2015简体中文版安装 导航 介绍 解决安装先决条件 安装 VS2015 创建桌面快捷方式 启动 VS2015 命令启动VS2015 配置 VS2015 启动完成 MSDN安装 启动MSDN Visual Studio的功能添加和删除 Visual Studio的卸载 补一张安装完成的 介绍    返回顶部 由于安装在不同的操作系统中会遇到不同错误的提示 所以,不会在本篇文章中介绍 Visual Studio2015 在不同操作系统的安装方法. 如果在安装过程中遇到了问题 请在百度中搜索相关

windows 32位系统中进程最大可用内存空间为3GB (转)

http://msdn.microsoft.com/zh-cn/library/ms189334.aspx 进程地址空间 所有 32 位应用程序都有 4 GB 的进程地址空间(32 位地址最多可以映射 4 GB 的内存).对于 Microsoft Windows 操作系统,应用程序可以访问 2 GB 的进程地址空间,称为用户模式虚拟地址空间.应用程序拥有的所有线程都共享同一个用户模式虚拟地址空间.其余 2 GB 为操作系统保留(也称为内核模式地址空间).所有操作系统版本(从 Windows 20

leetcode——190 Reverse Bits(32位无符号二进制数的翻转)

Reverse bits of a given 32 bits unsigned integer. For example, given input 43261596 (represented in binary as 00000010100101000001111010011100), return 964176192 (represented in binary as 00111001011110000010100101000000). Follow up: If this function