`
sysu_zeh
  • 浏览: 28153 次
  • 性别: Icon_minigender_1
  • 来自: 广州
最近访客 更多访客>>
社区版块
存档分类
最新评论

位操作技巧

F# 
阅读更多
检测一个无符号数是不为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>

下舍入到2k次方的倍数:
1.x & ((-1)< 2.(((unsigned)x)>>k)<<k></k>
上舍入:
1. t = (1< 2.t = (-1)<<k x="(x-t-1)&amp;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中对应于掩码m1位的位,如: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>


位置换:
325位数表示从最低位开始的位的目标位置,结果是一个32*5的位矩阵,
将该矩阵沿次对角线转置后用532位字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] ;//
乘法可用移位和加完成
}
分享到:
评论
1 楼 xo_tobacoo 2009-02-12  
很想看看,可是干扰的字符太多,请清理下哦!

相关推荐

    C++位操作技巧.docx

    C++位操作技巧,操作方面的一些总结

    Bit Twiddling(位操作技巧!)

    位操作技巧,驱动开发,嵌入式,操作系统的高手进阶学习!

    MarkRepo#MarkRepo.github.io#2021-01-01-位操作技巧总结1

    1. 利用或操作 | 和空格将英文字符转换为小写 2. 利用与操作 & 和下划线将英文字符转换为大写 3. 利用异或操作 ^ 和空格进行英文字符大小写互换 4.

    java 位操作集合以及应用技巧

    位操作,很强大。由于在工作中遇到一次,基本不会,为了学习,就整理了一下,集中学习了次。为以后的使用提供参照。

    研华Webaccess技巧之---取位操作.rar

    研华Webaccess技巧之---取位操作rar,研华Webaccess技巧之---取位操作

    WORD中高级编辑操作技巧之全集.

    word操作技巧大部分都是高级操作技巧。没事多看看,绝对可以胜任一位合格的秘书职位。

    经典的位运算合集 Matrix67及总结

    【转载】常用位操作 位运算应用口诀 常用位操作 几个常用的位操作 计算树状数组lowbit的三种方法 统计一个整数的二进制中1的个数(位运算技巧) 收藏 统计一个整数的二进制中1的个数的三种方法 位运算讲稿_by_...

    C语言笔记(个人收集的很有用的C语言资料)

    这个是我平时收集的C语言资料有内存对齐,printf和scanf技巧,C运行时原理,malloc原理,位操作技巧,typedef和sizeof关键字的用法,以及宏的使用。对大家进一步了解C语言有一定得好处。

    位操作符的使用技巧

    在C语言编程中,数据的位是可以操作的最小数据单位,理论上可以用“位运算”来完成所有的运算和操作。一般的位操作是用来控制硬件的,或者做数据变换使用,但是,灵活的位操作可以有效地提高程序运行的效率。

    leroyg#leetcode-algorithm#常用的位操作1

    常用的位操作本文分两部分,第一部分列举几个有趣的位操作,第二部分讲解算法中常用的 n & (n - 1) 操作,顺便把用到这个技巧的算法题列出来讲解一下。(关于

    word长文档编辑技巧

    Word实用操作技巧之文字编辑 83 巧改Word下划线与文字间的距离 85 Office 2003新实例:打包刻录 86 Word2000中上下标的四种输入方法 88 Office Word打印设置技巧六则 90 去除Word文档中的页眉横线 92 用好Word 2003...

    .net平台操作技巧精选(中、英)

    一位美国人通过自己多年的 .net开发经验总结的实用开发技巧。

    研华Webaccess技巧之---取位操作

    介绍了关于研华Webaccess技巧之---取位操作的详细说明,提供研华数采的技术资料的下载。

    emmc读写操作技巧和一些名词释义

    从网上找到的某位牛人总结的emmc读写操作方面的一些技巧,有这方面需要的同仁可以拿去

    Excel使用技巧大全

    6. 如何消除缩位后的计算误差(微软OFFICE技巧大赛获奖作品) 41 7. 利用选择性粘贴命令完成一些特殊的计算 41 8. WEB查询 41 9. 在EXCEL中进行快速计算 42 10. 自动筛选前10个 42 11. 同时进行多个单元格的运算...

    单片机C51位运算应用技巧

    位运算符的应用 (源操作数s 掩码mask) (1) 按位与-- & 1 清零特定位 (mask中特定位置0,其它位为1,s=s&mask) 2 取某数中指定位 (mask中特定位置1,其它位为0,s=s&mask) (2) 按位或-- | 常用来将源操作数某些...

    令人敬畏的位:精选的令人敬畏的按位操作和技巧列表

    很棒的位 精选的按位操作和技巧列表维护者请随时整数设置第n位x | (1&lt;&lt;n xss=removed&gt;&gt; 1;v |= v &gt;&gt; 2;v |= v &gt;&gt; 4;v |= v &gt;&gt; 8;v |= v &gt;&gt; 16;v++;舍入/舍入一个数字n &gt;&gt; 05.7812 &gt;&gt; 0 // 5获取最大整数int ...

    Excel使用技巧集锦—163种使用技巧大全(超全).doc

    150. 如何消除缩位后的计算误差(微软OFFICE技巧大赛获奖作品) 87 151. 利用选择性粘贴命令完成一些特殊的计算 87 152. WEB查询 88 153. 在EXCEL中进行快速计算 89 154. 自动筛选前10个 89 155. 同时进行多个单元格...

    技巧篇:pyspark常用操作梳理

    pyspark常用操作梳理 基于spark.sql进行操作 创建临时表 创建临时视图 基于dataframe进行操作 了解表结构 查看数据 查看列名 持久化 列操作 列名称重命名 条件筛选 利用when做条件判断 利用between做...

    JSP实用技巧集合,jsp编程的一些小技巧总结

    jsp编程的一些小技巧总结,绝对实用。包括JSP编程中常用的js技术。 1.JSP编程中常用的js技术 2. 在下拉列表框里选择一个值后跳出新窗口? 3. 在JSP中启动execl? 4. 两级下拉列表框联动菜单? 5. java中如何把一个目录...

Global site tag (gtag.js) - Google Analytics