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

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. jquery可拖动表格调整列格子的宽度大小(转)

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. jQuery分页小插件

    源码如下: $.fn.pager = function (pagerInfo) { var recordCount = this.size(); if (recordCount <= pager ...

  3. 点击edittext并显示其内容

    package com.example.sum;//sum import com.example.sum.R;//sum import android.app.Activity; import and ...

  4. 005杰信-factory删除数据

    factory表的删除分为两种:单行删除,以及批量删除. 过程:在jFactoryCreate.jsp页面上两个按钮,单行删除以及批量删除.

  5. 监听过多,会抛tooManyListener例外

    在生成一个窗体的时候,点击窗体的右上角关闭按钮激发窗体事件的方法:窗体Frame为事件源,WindowsListener接口调用Windowsclosing(). 为了配合后面的实现,我们必须将Win ...

  6. 【BZOJ】1660: [Usaco2006 Nov]Bad Hair Day 乱发节(单调栈)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1660 单调栈裸题..累计比每一个点高的个数即可. #include <cstdio> # ...

  7. Codeforces Round #311 (Div. 2) A,B,C,D,E

    A. Ilya and Diplomas 思路:水题了, 随随便便枚举一下,分情况讨论一下就OK了. code: #include <stdio.h> #include <stdli ...

  8. POJ2139 Six Degrees of Cowvin Bacon [Floyd]

    水题,随手敲过 一看就是最短路问题,a,b演同一场电影则他们的距离为1 默认全部两两原始距离无穷,到自身为0 输入全部数据处理后floyd 然后照它说的求平均分离度 再找最小的,×100取整输出 #i ...

  9. Net性能分析与调试培训资料

    https://wenku.baidu.com/view/76340ccc02d276a200292e51.html

  10. Oracle正式发布VirtualBox 5.0.22版本

    甲骨文(Oracle)正式发布了VirtualBox 5.0.22版本,该开源和跨平台虚拟化软件的最新维护版本已经面向所有支持平台开放,引入了诸多新特性和功能改善推荐用户尽早完成升级.新版本在Linu ...