求下面函数的返回值(微软)

int func(x) 

    int countx = 0; 
    while(x) 
    { 
          countx ++; 
          x = x&(x-1); 
     } 
    return countx; 
}

假定x = 9999。 答案:8

思路:将x转化为2进制,看含有的1的个数。

求下面函数的返回值(微软) -- 统计1的个数
-------------------------------------
int func(int x)
{
    int countx = 0;
    while(x)
    {
        countx++;
        x = x&(x-1);
    }
    return countx;
}

假定x = 9999
10011100001111
答案: 8

思路: 将x转化为2进制,看含有的1的个数。
注: 每执行一次x = x&(x-1),会将x用二进制表示时最右边的一个1变为0,因为x-1将会将该位(x用二进制表示时最右边的一个1)变为0。

判断一个数(x)是否是2的n次方?
-------------------------------------
#include <stdio.h>

int func(int x)
{
    if( (x&(x-1)) == 0 )//只有二进制含有1个1的时候,x是2 的n次方!!!
        return 1;
    else
        return 0;
}

int main()
{
    int x = 8;
    printf("%d\n", func(x));
}

注: 
(1) 如果一个数是2的n次方,那么这个数用二进制表示时其最高位为1,其余位为0。
(2) == 优先级高于 &

网友1:

x=x&(x-1) 
============== 
以前没有见过这样的表达式,分析一下发现发明这个表达式的人是个高手。 
表达式的意思就是把x的二进制表示从最低位直到遇到第一个1的比特置0。 
例如: 
e1: 
x          =   01001000 
x-1       =   01000111 
x&(x-1)=01000000 
e2: 
x           =   01001001 
x-1       =   01001000 
x&(x-1)=01001000
 
我的总结:
就用e1作为例子
第一次位于运算的结果是01000000
那么继续x-1,则x-1=00111111
那么继续位于运算:
01000000&00111111=00000000
此时循环的变量x为0,循环终止。
用来计数的countx也就是说明了二进制数种有几个1.
但是我们传进去的参数是整数,例如传9999呢?
看到&运算,肯定是变成二进制算,所以传什么就是多虑了。
 
 
 
网友2:
位运算。 
&是位与。
我觉得楼主应该知道&这个是位运算中的位与运算, 
楼主只是想知道x=x&(x-1)到底有什么功能~~
网友3:
<Hacker 's   Delight> 这本书第1章就有介绍,这种算法是把一个二进制数最右边的一个1变成0。

一个简单的程序,先给出运算结果:

1011001 
1011000 
1010000 
1000000

这是代码:

#include   <stdio.h>

void   OutBin(int   n) 

int   a[32],   l   =   0;

if(n   ==   0)   { 
printf( "0 "); 
return; 
}

while(n   >   0)   { 
a[l++]   =   n   %   2; 
n   > > =   1; 
}

while(l--)   
printf( "%d ",   a[l]); 
}

int   main() 

int   x   =   89;

OutBin(x); 
printf( "\n ");

x   &=   x-1;

OutBin(x); 
printf( "\n ");

x   &=   x-1;

OutBin(x); 
printf( "\n ");

x   &=   x-1;

OutBin(x); 
printf( "\n ");

return   0; 
}

 
 
网友4:
那可以通过调试找出一点规律~~~ 
当   x   =   0,结果为0 
<0,0> , <1,0> , <2,0> , <3,2> , <4,0> , <5,4> , <6,4> , <7,6> , <8,0> , <9,8> , <10,8> , <11,10> , <12,8> , <13,12> , <14,12> , <15,14> , <16,0> , <17,16> , <18,16> , <19,18> , <20,16> , <21,16> , <22,20> , <23,22> , <24,16> , <25,24> , <26,24> , <27,26> , <28,24> , <29,28> , <30,28> , <31,30> , <32,0> ... 
所以得出结论为: 
当x为奇数的时候,x=x&(x-1)它的值相当于x   =   x-1;一样的效果~~~ 
当x为2的N次幂时,结果为0; 
其他希望下面人能找出一点规律出来~~~
 
 
网友5:
位运算里有学问呀, 
例如众所周知的交换算法: 
void   swap(int   i1,   int   i2) 

        i1   ^=   i2; 
        i2   ^=   i1; 
        i1   ^=   i2; 

还有,我今天看了Minix操作系统作者写的《操作系统   设计与实现》(写的比William   Stalling的《操作系统   内核与设计原理》有条理而且清晰紧凑得多,后者内容芜杂)中的页面替换算法之一矩阵法,就是用位运算实现的: 
假设内存分为n页,那么高速缓存一个n   x   n的比特矩阵,开始时全置0,如下(假设n=4): 
    0   1   2   3 
0   0   0   0   0 
1   0   0   0   0 
2   0   0   0   0 
3   0   0   0   0 
每次内存访问时,如果访问的是i页,那么先把矩阵的第i行置1,然后把矩阵的第i列置0,这样i行的二进制的值越小就表示i页最长时间最近没有被访问。例如假设访问的次序为0-2-3-1,那么该矩阵的变化过程为: 
    0   1   2   3 
0   0   1   1   1         0   1   0   1         0   1   1   0         0   0   1   0 
1   0   0   0   0         0   0   0   0         0   0   0   0         1   0   1   1 
2   0   0   0   0         1   1   0   1         1   1   0   0         1   0   0   0 
3   0   0   0   0         0   0   0   0         1   1   1   0         1   0   1   0 
第三个例子是Windows   GDI的二元和三元光栅操作的编码。比较复杂,就不讲了。
更正: 
void   swap(int   i1,   int   i2) 
改成: 
void   swap(int&   i1,   int&   i2)

二进制x&(x-1);的更多相关文章

  1. 使用struct处理二进制

    有的时候需要用python处理二进制数据,比如,存取文件.socket操作时.这时候,可以使用python的struct模块来完成. struct模块中最重要的三个函数是pack(), unpack( ...

  2. 如何开启MySQL 5.7.12 的二进制日志

    1. 打开/etc下的my.cnf文件 2. 编辑它,添加内容: log_bin=binary-log   #二进制日志的文件名 server_id=1  #必须指定server_id,这是MySQL ...

  3. 【.net 深呼吸】使用二进制格式来压缩XML文档

    在相当多的情况下,咱们写入XML文件默认是使用文本格式来写入的,如果XML内容是通过网络传输,或者希望节省空间,特别是对于XML文档较大的情况,是得考虑尽可能地压缩XML文件的大小. XmlDicti ...

  4. Javascript的二进制数据处理学习 ——nodejs环境和浏览器环境分别分析

    以前用JavaScript主要是处理常规的数字.字符串.数组对象等数据,基本没有试过用JavaScript处理二进制数据块,最近的项目中涉及到这方面的东西,就花一段时间学了下这方面的API,在此总结一 ...

  5. 浅析MySQL基于ROW格式的二进制日志

    上文分析的二进制日志实际上是基于STATEMENT格式的,下面我们来看看基于ROW格式的二进制日志,毕竟,两者对应的binlog事件类型也不一样,同时,很多童鞋反映基于ROW格式的二进制日志无法查到原 ...

  6. 浅析MySQL二进制日志

    查看MySQL二进制文件中的内容有两种方式 1.  mysqlbinlog 2.  SHOW BINLOG EVENTS [IN 'log_name'] [FROM pos] [LIMIT [offs ...

  7. asp.net将图片转成二进制存入数据库

    一.代码如下 int code = int.Parse(this.TextBox1.Text);//图片编码 string value = this.FileUpload1.PostedFile.Fi ...

  8. 二进制包安装MySQL数据库

    1.1二进制包安装MySQL数据库 1.1.1 安装前准备(规范) [root@Mysql_server ~]# mkdir -p /home/zhurui/tools ##创建指定工具包存放路径 [ ...

  9. sqlite3的图片的(二进制数据)存取操作

    sqlite3的图片的(二进制数据)存取操作   前言 上篇介绍了sqlite3的一些常用插入操作方法和注意事项,在实际项目中遇到了图片缓存的问题,由于服务器不是很稳定,且受到外界环境的干扰(例如断电 ...

  10. MySQL二进制日志

    一.二进制日志(The Binary Log) 1.简介 包含所有更新了的数据或者已经潜在更新了的数据(比如一条没有匹配任何行的delete语句) 包含所有更新语句执行时间的信息 不记录没有修改数据的 ...

随机推荐

  1. 逻辑斯特回归(logistic regression)与最大熵模型(maximum entropy model)

  2. MyBatis 使用简单的 XML或注解用于配置和原始映射

    MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis .My ...

  3. YII2与Thinkphp整合阿里云OSS

    前言: 如果上传的文件都和网站程序源代码放在一起:那是有相当多的弊端的: 1:静态文件会占用大量带宽: 2:服务器的成本略高: 常规的做法是把php源代码放到一台服务器上:图片等静态文件放在另一台服务 ...

  4. 哪些工具可以在word中快速绘制图形

    在数学试卷.论文.电子教案等编写过程中,我们经常要作出数学图形或图像,若用Word自身携带的绘图工具绘制,多有不便.比如一些曲线的形状很难画得像,画到位,作图时修修改改,颇为费力,所以需要借助一些辅助 ...

  5. WinError 5

    IDE工具:pychrm 语言:python 在使用os模块修改路径名称时,总是会报 WinError 5 这个错误,就是拒绝访问,之前也遇见过,就是要操作的当前路径里有文件已经打开,代码不能再次访问 ...

  6. pythonanywhere笔记

    https://www.pythonanywhere.com Deploying an existing Django project on PythonAnywhere Deploying a Dj ...

  7. string类(四、字符串比较相关)

    string类比较相关: 1. string.Compare [static] 1/ string.Compare(string A, string B); 比较两个string,返回整数表示二者在排 ...

  8. iOS开发之 -- 帧动画的使用

    在项目的开发过程中,我们经常会遇到使用动画的时候,比如我们在请求接口直接开始一个动画,请求结束后结束动画,下面我就给大家展示一个很方便的帧动画的用法: 代码如下: .h #import <Fou ...

  9. Django学习笔记第九篇--实战练习五--关于数据的改、删操作、数据库字段属性的设置和类视图

    一.首先上代码.关于类视图: class register(View): #template_name = "templates/register.html" def get(se ...

  10. 【黑金原创教程】 FPGA那些事儿《概念篇》

    简介一本讲述非软硬片上系统的书,另外还是低级建模的使用手册. 目录[黑金原创教程] FPGA那些事儿<概念篇>:File01 - 结构的玩笑[黑金原创教程] FPGA那些事儿<概念篇 ...