`
zhao103804
  • 浏览: 124618 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

位运算应用实例

阅读更多

位运算应用口诀 
清零取反要用与,某位置一可用或
若要取反和交换,轻轻松松用异或
移位运算
要点 1 它们都是双目运算符,两个运算分量都是整形,结果也是整形。
  2 "<<" 左移:右边空出的位上补0,左边的位将从字头挤掉,其值相当于乘2。
  3 ">>"右移:右边的位被挤掉。对于左边移出的空位,如果是正数则空位补0,若为负数,可能补0或补1,这取决于所用的计算机系统。
  4 ">>>"运算符,右边的位被挤掉,对于左边移出的空位一概补上0。
位运算符的应用 (源操作数s 掩码mask)
(1) 按位与-- &
1 清零特定位 (mask中特定位置0,其它位为1,s=s&mask)
2 取某数中指定位 (mask中特定位置1,其它位为0,s=s&mask)
(2) 按位或-- |
  常用来将源操作数某些位置1,其它位不变。 (mask中特定位置1,其它位为0 s=s|mask)
(3) 位异或-- ^
1 使特定位的值取反 (mask中特定位置1,其它位为0 s=s^mask)
2 不引入第三变量,交换两个变量的值 (设 a=a1,b=b1)
  目 标 操 作 操作后状态
a=a1^b1 a=a^b a=a1^b1,b=b1
b=a1^b1^b1 b=a^b a=a1^b1,b=a1
a=b1^a1^a1 a=a^b a=b1,b=a1
二进制补码运算公式:
-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
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比较
应用举例
(1) 判断int型变量a是奇数还是偶数  
a&1 = 0 偶数
  a&1 = 1 奇数
(2) 取int型变量a的第k位 (k=0,1,2……sizeof(int)),即a>>k&1
(3) 将int型变量a的第k位清0,即a=a&~(1<<k)
(4) 将int型变量a的第k位置1, 即a=a|(1<<k)
(5) int型变量循环左移k次,即a=a<<k|a>>16-k (设sizeof(int)=16)
(6) int型变量a循环右移k次,即a=a>>k|a<<16-k (设sizeof(int)=16)
(7)整数的平均值
对于两个整数x,y,如果用 (x+y)/2 求平均值,会产生溢出,因为 x+y 可能会大于INT_MAX,但是我们知道它们的平均值是肯定不会溢出的,我们用如下算法:
int average(int x, int y) //返回X,Y 的平均值
{  
  return (x&y)+((x^y)>>1);
}
(8)判断一个整数是不是2的幂,对于一个数 x >= 0,判断他是不是2的幂
boolean power2(int x)
{
  return ((x&(x-1))==0)&&(x!=0);
}
(9)不用temp交换两个整数
void swap(int x , int y)
{
  x ^= y;
  y ^= x;
  x ^= y;
}
(10)计算绝对值
int abs( int x ) 
{
int y ;
y = x >> 31 ;
return (x^y)-y ; //or: (x+y)^y
}
(11)取模运算转化成位运算 (在不产生溢出的情况下)
  a % (2^n) 等价于 a & (2^n - 1)
(12)乘法运算转化成位运算 (在不产生溢出的情况下)
  a * (2^n) 等价于 a<< n
(13)除法运算转化成位运算 (在不产生溢出的情况下)
  a / (2^n) 等价于 a>> n
  例: 12/8 == 12>>3
(14) a % 2 等价于 a & 1  
(15) if (x == a) x= b;
   else x= a;
   等价于 x= a ^ b ^ x;
(16) x 的 相反数 表示为 (~x+1) 


实例

  功能 | 示例 | 位运算
----------------------+---------------------------+--------------------
去掉最后一位 | (101101->10110) | x >> 1
在最后加一个0 | (101101->1011010) | x << 1
在最后加一个1 | (101101->1011011) | x << 1+1
把最后一位变成1 | (101100->101101) | x | 1
把最后一位变成0 | (101101->101100) | x | 1-1
最后一位取反 | (101101->101100) | x ^ 1
把右数第k位变成1 | (101001->101101,k=3) | x | (1 << (k-1))
把右数第k位变成0 | (101101->101001,k=3) | x & ~ (1 << (k-1))
右数第k位取反 | (101001->101101,k=3) | x ^ (1 << (k-1))
取末三位 | (1101101->101) | x & 7
取末k位 | (1101101->1101,k=5) | x & ((1 << k)-1)

取右数第k位 | (1101101->1,k=4) | x >> (k-1) & 1

把末k位变成1 | (101001->101111,k=4) | x | (1 << k-1)
末k位取反 | (101001->100110,k=4) | x ^ (1 << k-1)
把右边连续的1变成0 | (100101111->100100000) | x & (x+1)
把右起第一个0变成1 | (100101111->100111111) | x | (x+1)
把右边连续的0变成1 | (11011000->11011111) | x | (x-1)
取右边连续的1 | (100101111->1111) | (x ^ (x+1)) >> 1
去掉右起第一个1的左边 | (100101000->1000) | x & (x ^ (x-1))
判断奇数 (x&1)==1
判断偶数 (x&1)==0  

 

 

移位运算符

    包括:
    “>> 右移”;“<< 左移”;“>>> 无符号右移”

例子:
-5>>3=-1
1111 1111 1111 1111 1111 1111 1111 1011
1111 1111 1111 1111 1111 1111 1111 1111
其结果与 Math.floor((double)-5/(2*2*2)) 完全相同。

-5<<3=-40
1111 1111 1111 1111 1111 1111 1111 1011
1111 1111 1111 1111 1111 1111 1101 1000
其结果与 -5*2*2*2 完全相同。

5>>3=0
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0000 0000
其结果与 5/(2*2*2) 完全相同。

5<<3=40
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0010 1000
其结果与 5*2*2*2 完全相同。

-5>>>3=536870911     
1111 1111 1111 1111 1111 1111 1111 1011
0001 1111 1111 1111 1111 1111 1111 1111

无论正数、负数,它们的右移、左移、无符号右移 32 位都是其本身,比如 -5<<32=-5、-5>>32=-5、-5>>>32=-5。
一个有趣的现象是,把 1 左移 31 位再右移 31 位,其结果为 -1。
0000 0000 0000 0000 0000 0000 0000 0001
1000 0000 0000 0000 0000 0000 0000 0000
1111 1111 1111 1111 1111 1111 1111 1111


位逻辑运算符

    包括:
    & 与;| 或;~ 非(也叫做求反);^ 异或

    “& 与”、“| 或”、“~ 非”是基本逻辑运算,由此可以演变出“与非”、“或非”、“与或非”复合逻辑运算。“^ 异或”是一种特殊的逻辑运算,对它求反可以得到“同或”,所以“同或”逻辑也叫“异或非”逻辑。

例子:
5&3=1
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0000 0011
0000 0000 0000 0000 0000 0000 0000 0001

-5&3=3
1111 1111 1111 1111 1111 1111 1111 1011
0000 0000 0000 0000 0000 0000 0000 0011
0000 0000 0000 0000 0000 0000 0000 0011

5|3=7
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0000 0011
0000 0000 0000 0000 0000 0000 0000 0111

-5|3=-5
1111 1111 1111 1111 1111 1111 1111 1011
0000 0000 0000 0000 0000 0000 0000 0011
1111 1111 1111 1111 1111 1111 1111 1011

~5=-6
0000 0000 0000 0000 0000 0000 0000 0101
1111 1111 1111 1111 1111 1111 1111 1010

~-5=4
1111 1111 1111 1111 1111 1111 1111 1011
0000 0000 0000 0000 0000 0000 0000 0100

5^3=6
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0000 0011
0000 0000 0000 0000 0000 0000 0000 0110

-5^3=-8
1111 1111 1111 1111 1111 1111 1111 1011
0000 0000 0000 0000 0000 0000 0000 0011
1111 1111 1111 1111 1111 1111 1111 1000

 

 

注:网上收集所得,如有雷同,不必惊慌

分享到:
评论

相关推荐

    位运算.pdf 精心收集的资料,重新编辑

    5. 位运算应用实例: - `&`(按位与):清零特定位,提取特定位。 - `|`(按位或):设置特定位为1。 - `^`(位异或):翻转特定位,交换变量。 6. 二进制补码运算公式: - 补码运算可以用于简化加减乘除,如`x...

    C语言位运算+实例讲解

    &运算常应用于: 迅速清零 保留指定位 判断奇偶性 a & 1 = 1;则a为奇数 b & 1 = 0;则a为偶数 按位或| 按位或(“|”)用途:设定数据的指定位 按位异或^ 异或 就是位相同等于零,相异等于1 按位异或作用...

    位运算及其应用实例.docx

    在实际应用中,位运算常常用于: 1. 不使用临时变量交换两个整数。例如,方案1通过算术运算实现交换,虽然可能因溢出导致中间结果错误,但最终结果正确。而方案2则使用位运算,适用于整数且不会溢出问题。 2. 进制...

    位运算及其应用实例.pdf

    位运算的一个经典应用是在不使用额外变量的情况下交换两个整数。这里有两个常见的方法: - 方案1:使用算术运算,即`a = a + b; b = a - b; a = a - b;`。这种方法虽然简洁,但在数值过大可能导致溢出的情况下可能不...

    ACM位运算技巧

    本篇文章将深入探讨位运算中的各种技巧及其应用场景。 #### 基础位运算符 - **按位与(&)**:如果两个相应的二进制位都为1,则结果位为1;否则为0。 - 清零特定位:利用掩码中特定位置0,其余位为1,通过`&`操作...

    位运算大全

    8. **位运算的实例**: - 在嵌入式开发中,位运算用于控制硬件寄存器,通过设置、清除或检查特定位来实现功能。 - 在内存管理中,位运算可以用来计算地址对齐,如将指针向上调整到下一个字节、双字节或四字节的...

    实用位运算规则

    #### 五、应用实例 1. **判断整数的奇偶性** - `a & 1 == 0` 表示`a`为偶数。 - `a & 1 == 1` 表示`a`为奇数。 2. **获取特定比特位的值** - `a &gt;&gt; k & 1` 获取`a`的第`k`位的值。 3. **循环左移和循环右移** ...

    位运算常用操作总结

    #### 二、位运算应用口诀 - 清零取反要用与 - 某位置一可用或 - 若要取反和交换,轻轻松松用异或 - 移位运算 - 左移:右边空出的位上补0,左边的位将从字头挤掉,其值相当于乘2。 - 右移:右边的位被挤掉。对于...

    C中的位运算,讲的很详细

    #### 九、位运算的应用案例 1. **数据压缩与解压:** 在压缩算法中,通过对数据进行位操作,可以有效地减少数据的存储空间。 2. **硬件控制:** 在嵌入式系统开发中,经常需要通过位操作来控制硬件设备的状态,如...

    运算放大器应用技术手册中文版

    运算放大器技术手册的其他内容可能还会包括一些运算放大器的设计实例,解释如何根据特定的应用需求选择合适的运算放大器型号,以及如何在设计中充分发挥运算放大器的性能。在手册中,工程师和技术人员能够了解到运算...

    位运算教程

    位运算在很多实际场景中都有应用,比如内存管理、数据压缩、编码解码、硬件接口编程等。它们能够高效地处理位级别的操作,提高程序运行速度,减少资源消耗。在学习位运算时,需要理解二进制数的性质,掌握各种位...

    20191220-Java位运算_java_位运算_

    本文将深入讲解Java中的位运算,并通过雪花算法的应用实例来进一步阐述其重要性和用法。 1. **位运算概念** 位运算涉及到对整数类型(byte, short, int, long)的二进制表示进行操作。Java提供了六种基本的位...

    Java运算案例(算数运算+赋值运算+逻辑运算+关系运算+自增运算+自减运算+条件运算+位运算)

    在本案例中,我们将深入探讨八大类运算符:算数运算、赋值运算、逻辑运算、关系运算、自增运算、自减运算、条件运算以及位运算。这些运算符在编写Java代码时频繁使用,理解并熟练掌握它们对于编写高效、简洁的程序至...

    N皇后问题(位运算,C语言版)

    N皇后问题是计算机科学中经典的回溯算法应用实例,它要求在N×N的棋盘上放置N个皇后,使得任意两个皇后都不在同一行、同一列或同一条对角线上。这个问题具有很高的挑战性,因为它涉及到搜索空间的深度优先遍历和有效...

    位运算例程

    位运算在软件开发中的应用非常广泛,理解并熟练掌握位运算可以帮助开发者编写更高效、更节省资源的代码。在阅读和分析压缩包中的"位运算例程"时,可以进一步学习这些操作的实际运用场景和具体实现细节。

    运算放大器应用技术手册.zip

    《运算放大器应用技术手册》是一本详细阐述运放使用和设计的实用参考资料,它涵盖了运放的基本原理、电路配置以及在实际系统中的应用实例。 一、运算放大器基本概念 运算放大器是一种具有高输入阻抗、低输出阻抗、...

    运算放大器应用技术手册中文完整版

    运放即运算放大器(Operational Amplifier),是一种含有高增益...综上所述,运算放大器应用技术手册将为读者提供从基础知识到应用实例的全面介绍,帮助读者深入了解运放的使用方法,提高在模拟电子设计中的实践能力。

    整数位运算和二进制显示.zip

    1. Java的位运算符和位运算,包括基本操作和实际应用。 2. 使用Java构建图形用户界面,可能涉及Swing或JavaFX库,以及组件的使用和事件处理。 3. Eclipse IDE的使用,包括项目配置和构建过程。 4. 对象导向编程,...

    C#应用实例大全 含有很多的应用 适合学习

    在本《C#应用实例大全》中,您将深入学习C#编程语言的实际应用,涵盖了许多实用的案例,包括但不限于面积体积的计算、系统提示与提醒功能的实现、自定义类的设计以及文件读取操作。这份教程是为那些希望提升C#编程...

Global site tag (gtag.js) - Google Analytics