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

位操作技巧

阅读更多
检测一个无符号数是不为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++位操作技巧 C++位操作技巧是指在C++编程语言中使用位操作符来实现各种算法和技巧的集合。本文档总结了C++位操作技巧的各种应用,包括检测无符号数、位运算公式、二进制补码运算、比较运算、无分支代码、符号函数...

    Bit Twiddling(位操作技巧!)

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

    位操作全面总结

    因此,熟练掌握位操作技巧对于编程来说非常重要,尤其在面临性能优化和资源限制的场景中。 位操作的基础包括六种基本操作符:与(&)、或(|)、异或(^)、非(~)、左移()、右移(&gt;&gt;)。这些操作符对应着不同的位操作,分别...

    单片机c语言位操作

    ### 单片机C语言位操作详解 #### 一、位运算符介绍 在单片机编程中,尤其是使用C语言...在实际项目开发中,合理利用位操作技巧,可以有效提升产品的性能表现。希望读者能够深入理解这些知识点,并在实践中灵活运用。

    C语言位操作——复习笔记 绝好的学习资料

    - 复习笔记中可能涵盖了位操作的基础知识,包括每个位运算符的定义、实例和应用,以及一些常见的位操作技巧。 - 推荐的书籍如《C Primer Plus》和《C语言程序设计现代方法》等经典教材,都对位操作有详细的讲解。 ...

    信捷 XC系列PLC应用之位操作例程.rar

    学习和理解这些位操作技巧,不仅能够提高你的编程效率,还能使你更好地应对各种复杂的自动化控制问题。因此,深入研究“信捷 XC系列PLC应用之位操作例程.rar”中的内容,对于提升你在PLC领域的专业技能至关重要。

    MSP430位操作C语言编程

    ### MSP430位操作C语言编程知识点解析 #### 一、引言 在嵌入式系统开发领域,微控制器...以上内容介绍了MSP430位操作C语言编程的基本知识点,希望能够帮助开发者更好地理解和掌握MSP430系列微控制器的位操作技巧。

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

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

    单片机的C语言中位操作用法

    了解并熟练掌握这些位操作技巧,能帮助开发者编写出更高效、更精简的代码,更好地利用有限的硬件资源。在实际应用中,位操作常用于硬件寄存器的设置和状态检测,因为这些寄存器的每一位通常对应一个特定的功能或状态...

    ICCAVR的位操作

    在嵌入式系统开发中,特别是对于AVR单片机的编程,位操作是非常常见且重要的。ICCAVR编译器提供了对AVR处理器的位操作支持,这使得开发者能够...理解并熟练运用这些位操作技巧,能够使AVR单片机的程序更加高效、简洁。

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

    Java中的位操作是一种底层的、高效的编程技巧,它允许我们直接对二进制位进行操作。位操作在处理数据、优化代码性能等方面有着广泛的应用,尤其是在处理二进制流、节省内存资源或进行高效计算时。本文将深入探讨Java...

    凌阳61单片机实现12864液晶的显示程序 和61简单的位操作

    本教程将深入探讨如何使用凌阳61单片机驱动12864液晶,并介绍基本的位操作技巧。 首先,我们需要了解12864 LCD的基本工作原理。这种显示器通常具有128列和64行的点阵,可以显示16x16或8x8的字符。它通过串行或并行...

    CSAPP的datalab-位运算

    3. 位操作技巧:在位操作中,通过特定的位运算组合可以实现一些巧妙的功能,如快速判断一个数是否是2的幂次方。 三、实验步骤与解析 LAB2实验中,可能会涉及到以下内容: 1. 位操作实践:通过编写程序,实践使用...

    计算机语言的编程技巧

    在C语言中,位操作技巧包括位与(&)、位或(|)、位非(~)、位异或(^)、左移()、右移(&gt;&gt;)等。例如,通过位与操作可以屏蔽掉某个变量的某些位,而通过位或操作则可以为变量的某些位设置值。 5. 嵌入汇编语言的编程 在...

    位运算的妙用

    3. **常用位操作技巧** - **判断奇偶**: 判断一个数是否为偶数,可以通过检查其最低位(最右边的位)是否为0。如果为0,则是偶数,否则是奇数。例如,`if (a & 1) == 0`可以用来判断a是否为偶数。 - **交换两数**:...

    编程过程中常见移位操作

    ### 编程过程中常见移位操作 ...以上介绍的位操作技巧不仅能够提高程序的运行效率,还能帮助开发者更好地理解和掌握底层数据处理的原理。这些技巧在实际开发中有着广泛的应用,尤其是在性能要求较高的场景下。

    C语言编程技巧在C语言学习中的应用研究 (2).pdf

    3. 位操作技巧:位操作是针对计算机最小数据单位“位”的操作,它可以让代码更加简洁高效。但需要注意位操作可能带来的安全隐患,并根据实际情况谨慎使用。 在单片机C语言编程方面,文章进一步提出了几个实用的编程...

    奇偶比特位互换

    在创新工场的笔试题中,这样的问题可能旨在测试候选人的位操作技巧和逻辑思维能力。掌握比特位操作对于理解和编写高效算法至关重要,尤其是在内存有限或者计算资源紧张的嵌入式系统中。同时,这也是一种常见的面试题...

    位运算.docx

    位运算在计算机科学中扮演着...在面试中,尤其是IT巨头如微软、腾讯、百度、360等的笔试面试,位运算经常作为考察点,因此理解并灵活运用位操作技巧至关重要。通过学习和实践,可以提升编程能力和解决复杂问题的能力。

Global site tag (gtag.js) - Google Analytics