检测一个无符号数是不为2^n-1(^为幂): x&(x+1) <o:p></o:p>
将最右侧0位改为1位: x | (x+1) <o:p></o:p>
二进制补码运算公式:
-x = ~x + 1 = ~(x-1)
~x = -x-1
-(~x) = x+1
~(-x) = x-1
x+y = x - ~y - 1 = (x|y)+(x&y)
x-y = x + ~y + 1 = (x|~y)-(~x&y)
x^y = (x|y)-(x&y)
x|y = (x&~y)+y
x&y = (~x|y)-~x <o:p></o:p>
x==y: ~(x-y|y-x)
x!=y: x-y|y-x
x< y: (x-y)^((x^y)&((x-y)^x))
x<=y: (x|~y)&((x^y)|~(y-x))
x< y: (~x&y)|((~x|y)&(x-y))//无符号x,y比较
x<=y: (~x|y)&((x^y)|~(y-x))//无符号x,y比较 <o:p></o:p>
使用位运算的无分支代码: <o:p></o:p>
计算绝对值
int abs( int x )
{
int y ;
y = x >> 31 ;
return (x^y)-y ;//or: (x+y)^y
} <o:p></o:p>
符号函数:sign(x) = -1, x<0; 0, x == 0 ; 1, x > 0
int sign(int x)
{
return (x>>31) | (unsigned(-x))>>31 ;//x=-2^31时失败(^为幂)
} <o:p></o:p>
三值比较:cmp(x,y) = -1, x y
int cmp( int x, int y )
{
return (x>y)-(x-y) ;
} <o:p></o:p>
doz=x-y, x>=y; 0, x<y></y> int doz(int x, int y )
{
int d ;
d = x-y ;
return d & ((~(d^((x^y)&(d^x))))>>31) ;
} <o:p></o:p>
int max(int x, int y )
{
int m ;
m = (x-y)>>31 ;
return y & m | x & ~m ;
} <o:p></o:p>
不使用第三方交换x,y:
1.x ^= y ; y ^= x ; x ^= y ;
2.x = x+y ; y = x-y ; x = x-y ;
3.x = x-y ; y = y+x ; x = y-x ;
4.x = y-x ; x = y-x ; x = x+y ; <o:p></o:p>
双值交换:x = a, x==b; b, x==a//常规编码为x = x==a ? b :a ;
1.x = a+b-x ;
2.x = a^b^x ; <o:p></o:p>
下舍入到2的k次方的倍数:
1.x & ((-1)< 2.(((unsigned)x)>>k)<<k></k> 上舍入:
1. t = (1< 2.t = (-1)<<k x="(x-t-1)&amp;t"></k>
位计数,统计1位的数量:
1.
int pop(unsigned x)
{
x = x-((x>>1)&0x55555555) ;
x = (x&0x33333333) + ((x>>2) & 0x33333333 ) ;
x = (x+(x>>4)) & 0x<st1:chmetcnv w:st="on" tcsc="0" unitname="F" sourcevalue="0" numbertype="1" negative="False" hasspace="False">0f</st1:chmetcnv><st1:chmetcnv w:st="on" tcsc="0" unitname="F" sourcevalue="0" numbertype="1" negative="False" hasspace="False">0f</st1:chmetcnv><st1:chmetcnv w:st="on" tcsc="0" unitname="F" sourcevalue="0" numbertype="1" negative="False" hasspace="False">0f</st1:chmetcnv><st1:chmetcnv w:st="on" tcsc="0" unitname="F" sourcevalue="0" numbertype="1" negative="False" hasspace="False">0f</st1:chmetcnv> ;
x = x + (x>>8) ;
x = x + (x>>16) ;
return x & 0x<st1:chmetcnv w:st="on" tcsc="0" unitname="F" sourcevalue="3" numbertype="1" negative="False" hasspace="False">0000003f</st1:chmetcnv> ;
}
2.
int pop(unsigned x) {
static char table[256] = { 0,1,1,2, 1,2,2,3, ...., 6,7,7,8 } ;
return table[x&0xff]+table[(x>>8)&0xff]+table[(x>>16)&0xff]+table[(x>>24)] ;
} <o:p></o:p>
奇偶性计算:
x = x ^ ( x>>1 ) ;
x = x ^ ( x>>2 ) ;
x = x ^ ( x>>4 ) ;
x = x ^ ( x>>8 ) ;
x = x ^ ( x>>16 ) ;
结果中位于x最低位,对无符号x,结果的第i位是原数第i位到最左侧位的奇偶性 <o:p></o:p>
位反转:
unsigned rev(unsigned x)
{
x = (x & 0x55555555) << 1 | (x>>1) & 0x55555555 ;
x = (x & 0x33333333) << 2 | (x>>2) & 0x33333333 ;
x = (x & 0x<st1:chmetcnv w:st="on" tcsc="0" unitname="F" sourcevalue="0" numbertype="1" negative="False" hasspace="False">0f</st1:chmetcnv><st1:chmetcnv w:st="on" tcsc="0" unitname="F" sourcevalue="0" numbertype="1" negative="False" hasspace="False">0f</st1:chmetcnv><st1:chmetcnv w:st="on" tcsc="0" unitname="F" sourcevalue="0" numbertype="1" negative="False" hasspace="False">0f</st1:chmetcnv><st1:chmetcnv w:st="on" tcsc="0" unitname="F" sourcevalue="0" numbertype="1" negative="False" hasspace="False">0f</st1:chmetcnv>) << 4 | (x>>4) & 0x<st1:chmetcnv w:st="on" tcsc="0" unitname="F" sourcevalue="0" numbertype="1" negative="False" hasspace="False">0f</st1:chmetcnv><st1:chmetcnv w:st="on" tcsc="0" unitname="F" sourcevalue="0" numbertype="1" negative="False" hasspace="False">0f</st1:chmetcnv><st1:chmetcnv w:st="on" tcsc="0" unitname="F" sourcevalue="0" numbertype="1" negative="False" hasspace="False">0f</st1:chmetcnv><st1:chmetcnv w:st="on" tcsc="0" unitname="F" sourcevalue="0" numbertype="1" negative="False" hasspace="False">0f</st1:chmetcnv> ;
x = (x<<24) | ((x&0xff00)<<8) | ((x>>8) & 0xff00) | (x>>24) ;
return x ;
} <o:p></o:p>
递增位反转后的数:
unsigned inc_r(unsigned x)
{
unsigned m = 0x80000000 ;
x ^= m ;
if( (int)x >= 0 )
do { m >>= 1 ; x ^= m ; } while( x < m ) ;
return x ;
} <o:p></o:p>
混选位:
abcd efgh ijkl mnop ABCD EFGH IJKL MNOP->aAbB cCdD eEfF gGhH iIjJ kKlL mMnN oOpP
unsigned ps(unsigned x)
{
unsigned t ;
t = (x ^ (x>>8)) & 0x0000ff00; x = x ^ t ^ (t<<8) ;
t = (x ^ (x>>4)) & 0x<st1:chmetcnv w:st="on" tcsc="0" unitname="F" sourcevalue="0" numbertype="1" negative="False" hasspace="False">00f</st1:chmetcnv><st1:chmetcnv w:st="on" tcsc="0" unitname="F" sourcevalue="0" numbertype="1" negative="False" hasspace="False">000f</st1:chmetcnv>0; x = x ^ t ^ (t<<4) ;
t = (x ^ (x>>2)) & 0x<st1:chmetcnv w:st="on" tcsc="0" unitname="C" sourcevalue="0" numbertype="1" negative="False" hasspace="False">0c</st1:chmetcnv><st1:chmetcnv w:st="on" tcsc="0" unitname="C" sourcevalue="0" numbertype="1" negative="False" hasspace="False">0c</st1:chmetcnv><st1:chmetcnv w:st="on" tcsc="0" unitname="C" sourcevalue="0" numbertype="1" negative="False" hasspace="False">0c</st1:chmetcnv><st1:chmetcnv w:st="on" tcsc="0" unitname="C" sourcevalue="0" numbertype="1" negative="False" hasspace="False">0c</st1:chmetcnv>; x = x ^ t ^ (t<<2) ;
t = (x ^ (x>>1)) & 0x22222222; x = x ^ t ^ (t<<1) ;
return x ;
} <o:p></o:p>
位压缩:
选择并右移字x中对应于掩码m的1位的位,如:compress(abcdefgh,01010101)=0000bdfh
compress_left(x,m)操作与此类似,但结果位在左边: bdfh0000.
unsigned compress(unsigned x, unsigned m)
{
unsigned mk, mp, mv, t ;
int i ; <o:p></o:p>
x &= m ;
mk = ~m << 1 ;
for( i = 0 ; i < 5 ; ++i ) {
mp = mk ^ ( mk << 1) ;
mp ^= ( mp << 2 ) ;
mp ^= ( mp << 4 ) ;
mp ^= ( mp << 8 ) ;
mp ^= ( mp << 16 ) ;
mv = mp & m ;
m = m ^ mv | (mv >> (1< t = x & mv ;
x = x ^ t | ( t >> ( 1< mk = mk & ~mp ;
}
return x ;
} <o:p></o:p>
位置换:
用32个5位数表示从最低位开始的位的目标位置,结果是一个32*5的位矩阵,
将该矩阵沿次对角线转置后用5个32位字p[5]存放。
SAG(x,m) = compress_left(x,m) | compress(x,~m) ;
准备工作:
void init( unsigned *p ) {
p[1] = SAG( p[1], p[0] ) ;
p[2] = SAG( SAG( p[2], p[0]), p[1] ) ;
p[3] = SAG( SAG( SAG( p[3], p[0] ), p[1]), p[2] ) ;
p[4] = SAG( SAG( SAG( SAG( p[4], p[0] ), p[1]) ,p[2]), p[3] ) ;
}
实际置换:
int rep( unsigned x ) {
x = SAG(x,p[0]);
x = SAG(x,p[1]);
x = SAG(x,p[2]);
x = SAG(x,p[3]);
x = SAG(x,p[4]);
return x ;
} <o:p></o:p>
二进制码到GRAY码的转换:
unsigned B<st1:chmetcnv w:st="on" tcsc="0" unitname="g" sourcevalue="2" numbertype="1" negative="False" hasspace="False">2G</st1:chmetcnv>(unsigned B )
{
return B ^ (B>>1) ;
}
GRAY码到二进制码:
unsigned G2B(unsigned G)
{
unsigned B ;
B = G ^ (G>>1) ;
B = G ^ (G>>2) ;
B = G ^ (G>>4) ;
B = G ^ (G>>8) ;
B = G ^ (G>>16) ;
return B ;
} <o:p></o:p>
找出最左0字节的位置:
int zbytel( unsigned x )
{
static cahr table[16] = { 4,3,2,2, 1,1,1,1, 0,0,0,0, 0,0,0,0 } ;
unsigned y ;
y = (x&0x<st1:chmetcnv w:st="on" tcsc="0" unitname="F" sourcevalue="7" numbertype="1" negative="False" hasspace="False">7f</st1:chmetcnv><st1:chmetcnv w:st="on" tcsc="0" unitname="F" sourcevalue="7" numbertype="1" negative="False" hasspace="False">7f</st1:chmetcnv><st1:chmetcnv w:st="on" tcsc="0" unitname="F" sourcevalue="7" numbertype="1" negative="False" hasspace="False">7f</st1:chmetcnv><st1:chmetcnv w:st="on" tcsc="0" unitname="F" sourcevalue="7" numbertype="1" negative="False" hasspace="False">7f</st1:chmetcnv>) + 0x<st1:chmetcnv w:st="on" tcsc="0" unitname="F" sourcevalue="7" numbertype="1" negative="False" hasspace="False">7f</st1:chmetcnv><st1:chmetcnv w:st="on" tcsc="0" unitname="F" sourcevalue="7" numbertype="1" negative="False" hasspace="False">7f</st1:chmetcnv><st1:chmetcnv w:st="on" tcsc="0" unitname="F" sourcevalue="7" numbertype="1" negative="False" hasspace="False">7f</st1:chmetcnv><st1:chmetcnv w:st="on" tcsc="0" unitname="F" sourcevalue="7" numbertype="1" negative="False" hasspace="False">7f</st1:chmetcnv> ;
y = ~(y|x|0x<st1:chmetcnv w:st="on" tcsc="0" unitname="F" sourcevalue="7" numbertype="1" negative="False" hasspace="False">7f</st1:chmetcnv><st1:chmetcnv w:st="on" tcsc="0" unitname="F" sourcevalue="7" numbertype="1" negative="False" hasspace="False">7f</st1:chmetcnv><st1:chmetcnv w:st="on" tcsc="0" unitname="F" sourcevalue="7" numbertype="1" negative="False" hasspace="False">7f</st1:chmetcnv><st1:chmetcnv w:st="on" tcsc="0" unitname="F" sourcevalue="7" numbertype="1" negative="False" hasspace="False">7f</st1:chmetcnv>) ;
return table[y*0x00204081 >> 28] ;//乘法可用移位和加完成
}
分享到:
相关推荐
C++位操作技巧,操作方面的一些总结
位操作技巧,驱动开发,嵌入式,操作系统的高手进阶学习!
1. 利用或操作 | 和空格将英文字符转换为小写 2. 利用与操作 & 和下划线将英文字符转换为大写 3. 利用异或操作 ^ 和空格进行英文字符大小写互换 4.
位操作,很强大。由于在工作中遇到一次,基本不会,为了学习,就整理了一下,集中学习了次。为以后的使用提供参照。
研华Webaccess技巧之---取位操作rar,研华Webaccess技巧之---取位操作
word操作技巧大部分都是高级操作技巧。没事多看看,绝对可以胜任一位合格的秘书职位。
【转载】常用位操作 位运算应用口诀 常用位操作 几个常用的位操作 计算树状数组lowbit的三种方法 统计一个整数的二进制中1的个数(位运算技巧) 收藏 统计一个整数的二进制中1的个数的三种方法 位运算讲稿_by_...
这个是我平时收集的C语言资料有内存对齐,printf和scanf技巧,C运行时原理,malloc原理,位操作技巧,typedef和sizeof关键字的用法,以及宏的使用。对大家进一步了解C语言有一定得好处。
在C语言编程中,数据的位是可以操作的最小数据单位,理论上可以用“位运算”来完成所有的运算和操作。一般的位操作是用来控制硬件的,或者做数据变换使用,但是,灵活的位操作可以有效地提高程序运行的效率。
常用的位操作本文分两部分,第一部分列举几个有趣的位操作,第二部分讲解算法中常用的 n & (n - 1) 操作,顺便把用到这个技巧的算法题列出来讲解一下。(关于
Word实用操作技巧之文字编辑 83 巧改Word下划线与文字间的距离 85 Office 2003新实例:打包刻录 86 Word2000中上下标的四种输入方法 88 Office Word打印设置技巧六则 90 去除Word文档中的页眉横线 92 用好Word 2003...
一位美国人通过自己多年的 .net开发经验总结的实用开发技巧。
介绍了关于研华Webaccess技巧之---取位操作的详细说明,提供研华数采的技术资料的下载。
从网上找到的某位牛人总结的emmc读写操作方面的一些技巧,有这方面需要的同仁可以拿去
6. 如何消除缩位后的计算误差(微软OFFICE技巧大赛获奖作品) 41 7. 利用选择性粘贴命令完成一些特殊的计算 41 8. WEB查询 41 9. 在EXCEL中进行快速计算 42 10. 自动筛选前10个 42 11. 同时进行多个单元格的运算...
位运算符的应用 (源操作数s 掩码mask) (1) 按位与-- & 1 清零特定位 (mask中特定位置0,其它位为1,s=s&mask) 2 取某数中指定位 (mask中特定位置1,其它位为0,s=s&mask) (2) 按位或-- | 常用来将源操作数某些...
很棒的位 精选的按位操作和技巧列表维护者请随时整数设置第n位x | (1<<n xss=removed>> 1;v |= v >> 2;v |= v >> 4;v |= v >> 8;v |= v >> 16;v++;舍入/舍入一个数字n >> 05.7812 >> 0 // 5获取最大整数int ...
150. 如何消除缩位后的计算误差(微软OFFICE技巧大赛获奖作品) 87 151. 利用选择性粘贴命令完成一些特殊的计算 87 152. WEB查询 88 153. 在EXCEL中进行快速计算 89 154. 自动筛选前10个 89 155. 同时进行多个单元格...
pyspark常用操作梳理 基于spark.sql进行操作 创建临时表 创建临时视图 基于dataframe进行操作 了解表结构 查看数据 查看列名 持久化 列操作 列名称重命名 条件筛选 利用when做条件判断 利用between做...
jsp编程的一些小技巧总结,绝对实用。包括JSP编程中常用的js技术。 1.JSP编程中常用的js技术 2. 在下拉列表框里选择一个值后跳出新窗口? 3. 在JSP中启动execl? 4. 两级下拉列表框联动菜单? 5. java中如何把一个目录...