几个常用的位操作

简介:

下面的结论都是基于用补码表示负数的计算机平台
 1 None.gif void  main(unsigned  int  x)
 2 ExpandedBlockStart.gif {     
 3InBlock.gif     //判断无符号整数x是否是2的幂 
 4InBlock.gif     if(x&(x-1))//若一个数是2的幂,则除最高位为1外,其余位均为0(二进制表示,下同)
 5InBlock.gif         printf("False\n");
 6InBlock.gif     else
 7InBlock.gif         printf("True\n");
 8InBlock.gif                      
 9InBlock.gif     //判断一个无符号整数是否为2^n-1的形式(原理同上) 
10InBlock.gif     if(x&(x+1))//若为2^n-1,则低位全为1 
11InBlock.gif         printf("False\n");
12InBlock.gif     else
13InBlock.gif         printf("True\n"); 
14InBlock.gif         
15InBlock.gif     //整数能被最大的2的幂(?)整除 : 析出最右侧为1的位
16InBlock.gif     //e.g.: 100->4
17InBlock.gif     printf("%d\n",x&(-x));//将其余位置0 
18InBlock.gif     
19InBlock.gif     //析出最右侧为0的位(原理同上) 
20InBlock.gif     //e.g.:111b->1000b, 10->1
21InBlock.gif     printf("%d\n",~x&(x+1));//将该位置1,其余位置0
22InBlock.gif     
23InBlock.gif     //识别后缀0的掩码(将右侧连续的0位置1,其余各位置0)
24InBlock.gif     //e.g.:1100b->0011b
25InBlock.gif     printf("%d\n"~x&(x-1));  //或 
26InBlock.gif     printf("%d\n"~(x|-x));   //或 
27InBlock.gif     printf("%d\n", (x&-x)-1);
28InBlock.gif     
29InBlock.gif     //识别最右侧的1未和后缀0的掩码(将最右侧的1位保留,并将其后面所有的0位置1) 
30InBlock.gif     //e.g.:1100b->0111b
31InBlock.gif     printf("%d\n", x^(x-1)); 
32InBlock.gif     
33InBlock.gif     //向右传播最右侧的1位 
34InBlock.gif     //e.g.:1100b->1111b
35InBlock.gif     printf("%d\n", x|(x-1));
36InBlock.gif     
37InBlock.gif     //将最右侧连续的1位置0
38InBlock.gif     //e.g.:10110b->10000
39InBlock.gif     printf("%d\n", ((x|(x-1))+1)&x);     
40ExpandedBlockEnd.gif}


计算x中有多少个为1的位:
 1 None.gif int  Count1( int  x)
 2 ExpandedBlockStart.gif {
 3InBlock.gif    int n = 0;
 4InBlock.gif    while(x)
 5ExpandedSubBlockStart.gif    {
 6InBlock.gif            n++;
 7InBlock.gif            x&=x-1;
 8ExpandedSubBlockEnd.gif    }

 9InBlock.gif    return n;
10ExpandedBlockEnd.gif}


获取下一个具有同样数量的1位的更大的数;应用:在用位串表示集合的子集时 
1 None.gif unsigned snoob(unsigned x)
2 ExpandedBlockStart.gif {
3InBlock.gif    unsigned smallest, ripple, ones;//e.g.: x=XXX0 1111 0000
4InBlock.gif    smallest = x & -x;              //        0000 0001 0000
5InBlock.gif    ripple = x + smallest;          //        XXX1 0000 0000
6InBlock.gif    ones = x ^ ripple;              //        0001 1111 0000
7InBlock.gif    ones = (ones >> 2/ smallest;  //        0000 0000 0111
8InBlock.gif    return ripple | ones;           //        XXX1 0000 0111
9ExpandedBlockEnd.gif}


本文转自Silent Void博客园博客,原文链接:http://www.cnblogs.com/happyhippy/archive/2007/04/24/725127.html ,如需转载请自行联系原作者
相关文章
|
5月前
|
C语言
写一个宏,可以将一个整数的二进制位的奇数位和偶数位交换(C语言)
写一个宏,可以将一个整数的二进制位的奇数位和偶数位交换(C语言)
38 0
|
4月前
|
存储 C#
C# 逻辑位运符及运算原理 按位操作二进制
C# 逻辑位运符及运算原理 按位操作二进制
|
2月前
|
C语言
C语言自增减、逻辑运算、位运算、位移运算及三目运算操作
C语言自增减、逻辑运算、位运算、位移运算及三目运算操作
17 0
|
5月前
位操作(异或骚操作)
位操作(异或骚操作)
25 0
|
8月前
|
算法 Python
如何将算法翻译成RTL(四)有符号数的加减法实现
如何将算法翻译成RTL(四)有符号数的加减法实现
98 0
|
10月前
深入理解位操作( 一)
深入理解位操作( 一)
48 0
|
编译器
C位操作
C位操作
125 0
C位操作
|
C语言
【C语言】写一个宏实现将一个整数的二进制的奇数位和偶数位交换
【C语言】写一个宏实现将一个整数的二进制的奇数位和偶数位交换
79 0
【C语言】写一个宏实现将一个整数的二进制的奇数位和偶数位交换
|
人工智能 BI
第三次笔记:算术逻辑单元 电路基本原理 加法器的设计 一位全加器 串行进位加法器 并行进位加法器 补码加减运算器 无符号整数加减法 标志位的生成
第三次笔记:算术逻辑单元 电路基本原理 加法器的设计 一位全加器 串行进位加法器 并行进位加法器 补码加减运算器 无符号整数加减法 标志位的生成
306 0
第三次笔记:算术逻辑单元 电路基本原理 加法器的设计 一位全加器 串行进位加法器 并行进位加法器 补码加减运算器 无符号整数加减法 标志位的生成