位运算和典型应用详解

位运算的符号
  与运算:&

  或运算:|

  异或运算:^

  非运算:~

  移位运算:>>和<<

一. 逻辑运算符
1. & 位与运算

1) 运算规则
位与运算的实质是将参与运算的两个数据,按对应的二进制数逐位进行逻辑与运算。例如:int型常量4和7进行位与运算的运算过程如下:
4=0000 0000 0000 0100 &7 =0000 0000 0000 0111= 0000 0000 0000 0100
对于负数,按其补码进行运算。例如:例如:int型常量-4和7进行位与运算的运算过程如下: -4=1111 1111 1111 1100 &7 =0000 0000 0000 0111= 0000 0000 0000 0100
2) 典型应用
(1) 清零
清零:快速对某一段数据单元的数据清零,即将其全部的二进制位为0。例如整型数a=321对其全部数据清零的操作为a=a&0x0。 321=0000 0001 0100 0001 &0=0000 0000 0000 0000
= 0000 0000 0000 0000
(2) 获取一个数据的指定位
获取一个数据的指定位。例如获得整型数a=的低八位数据的操作为a=a&0xFF。321=
0000 0001 0100 0001 & 0xFF =0000 0000 1111 11111
= 0000 0000 0100 0001
获得整型数a=的高八位数据的操作为a=a&0xFF00。==a&0XFF00==
321=0000 0001 0100 0001 & 0XFF00=1111 1111 0000 0000
= 0000 0001 0000 0000
(3)保留数据区的特定位
保留数据区的特定位。例如获得整型数a=的第7-8位(从0开始)位的数据操作为: 110000000
321=0000 0001 0100 0001 & 384=0000 0001 1000 0000
=0000 0001 0000 0000
(4)判断一个数X是否是2的N次方,不可以使用循环语句
如果X减去1后(低一位并且二进制的每一位都是1),这个数与X做与运算,答案若是0,则X是2的N次方。
!(X&(X-1))

2. | 位或运算
1) 运算规则
位或运算的实质是将参与运算的两个数据,按对应的二进制数逐位进行逻辑或运算。例如:int型常量5和7进行位或运算的表达式为5|7,结果如下:5= 0000 0000 0000 0101
| 7= 0000 0000 0000 0111=0000 0000 0000 0111
2) 主要用途
(1) 设定一个数据的指定位。例如整型数a=321,将其低八位数据置为1的操作为a=a|0XFF。321= 0000 0001 0100 0001 | 0000 0000 1111 1111=0000 0000 1111 1111
逻辑运算符||与位或运算符|的区别
条件“或”运算符 (||) 执行 bool 操作数的逻辑“或”运算,但仅在必要时才计算第二个操作数。 x || y , x | y 不同的是,如果 x 为 true,则不计算 y(因为不论 y 为何值,“或”操作的结果都为 true)。这被称作为“短路”计算。
3. ^ 位异或
1) 运算规则
位异或运算的实质是将参与运算的两个数据,按对应的二进制数逐位进行逻辑异或运算。只有当对应位的二进制数互斥的时候,对应位的结果才为真。例如:int型常量5和7进行位异或运算的表达式为5^7,结果如下:5=0000 0000 0000 0101^7=0000 0000 0000 0111
= 0000 0000 0000 0010
2) 典型应用
(1)定位翻转
定位翻转:设定一个数据的指定位,将1换为0,0换为1。例如整型数a=321,,将其低八位数据进行翻位的操作为a=a^0XFF;
(2)数值交换
数值交换。例如a=3,b=4。在例11-1中,无须引入第三个变量,利用位运算即可实现数据交换。以下的操作可以实现a,b两个数据的交换:
a=a^b;
b=b^a;
a=a^b;
4.~ 位非
位非运算的实质是将参与运算的两个数据,按对应的二进制数逐位进行逻辑非运算。

二.位移运算符
1.位左移
左移运算的实质是将对应的数据的二进制值逐位左移若干位,并在空出的位置上填0,最高位溢出并舍弃。例如int a,b;
a=5;
b=a<<2;
则b=20,分析过程如下:
(a)10=(5)10=(0000 0000 0000 0101)2
b=a<<2;
b=(0000 0000 0001 0100)2=(20)10
从上例可以看出位运算可以实现二倍乘运算。由于位移操作的运算速度比乘法的运算速度高很多。因此在处理数据的乘法运算的时,采用位移运算可以获得较快的速度。
提示 将所有对2的乘法运算转换为位移运算,可提高程序的运行效率
2.位右移
位右移运算的实质是将对应的数据的二进制值逐位右移若干位,并舍弃出界的数字。如果当前的数为无符号数,高位补零。例如:
int (a)10=(5)10=(0000 0000 0000 0101)2
b=a>>2;
b=(0000 0000 0000 0001)2=(1)10
如果当前的数据为有符号数,在进行右移的时候,根据符号位决定左边补0还是补1。如果符号位为0,则左边补0;但是如果符号位为1,则根据不同的计算机系统,可能有不同的处理方式。可以看出位右移运算,可以实现对除数为2的整除运算。
提示 将所有对2的整除运算转换为位移运算,可提高程序的运行效率
3.复合的位运算符
在C语言中还提供复合的位运算符,如下:
&=、!=、>>=、<<=和^=
例如:a&=0x11等价于 a= a&0x11,其他运算符以此类推。
不同类型的整数数据在进行混合类型的位运算时,按右端对齐原则进行处理,按数据长度大的数据进行处理,将数据长度小的数据左端补0或1。例如char a与int b进行位运算的时候,按int 进行处理,char a转化为整型数据,并在左端补0。
补位原则如下:
1) 对于有符号数据:如果a为正整数,则左端补0,如果a 为负数,则左端补1。
2) 对于无符号数据:在左端补0。
4.例子
例11-2 获得一个无符号数据从第p位开始的n位二进制数据。假设数据右端对齐,第0位二进制数在数据的最右端,获得的结果要求右对齐。
#include <stdio.h>
/*getbits:获得从第p位开始的n位二进制数 */
unsigned int getbits(unsigned int x, unsigned int p, unsigned n)
{
unsigned int a;
unsigned int b;
a=x>>(p+1);
b=~(~0<<n);
return a&b;
}
提示 在某一平台进行程序开发时,首先要求了解此系统的基本数据类型的有效范围, 对涉及的位运算进行评估,特别是要对边界数据进行检测,确保计算正确。

原文标题:位运算及其应用详解

原文地址:http://blog.chinaunix.net/uid-21411227-id-1826986.html

时间: 2024-11-08 08:03:28

位运算和典型应用详解的相关文章

Twitter-Snowflake,64位自增ID算法详解

Twitter-Snowflake算法产生的背景相当简单,为了满足Twitter每秒上万条消息的请求,每条消息都必须分配一条唯一的id,这些id还需要一些大致的顺序(方便客户端排序),并且在分布式系统中不同机器产生的id必须不同. snowflake把时间戳,工作机器id,序列号组合在一起. 除了最高位bit标记为不可用以外,其余三组bit占位均可浮动,看具体的业务需求而定.以下关于此算法的可行性研究 Console.WriteLine("41bit的时间戳可以支持该算法使用年限:{0}&quo

数学,位运算,典型题

数学,自然想到组合数,逆元,阶乘 先来一发组合数相关, #define MAXN 200001 const int mod=1000000007; typedef long long ll; int n,m,r,c; ll ans,s; ll inv[MAXN],fac[MAXN],dev[MAXN]; //inv[]逆元,fac[]阶乘,dev[]阶乘的逆元 void chuli(int x) { inv[1]=1; fac[1]=1; dev[1]=1; fac[0]=1; dev[0]=1

位运算的妙用

位运算所有语言里面都有位运算,&,|,^,~,<<,>>,>>>,但是其他语言不清楚,前端估计许多人直接一扫而过,甚至把这玩意和逻辑或与混淆,甚至有的不认识<<,>>>,问这什么意思的那是许多许多.由于这个运算属于底层的二进制的运算,不做详解(详解的话,阅读不易,而且许多人功力不够),只讲一些常用的,(注意位运算性能更好,且容易装逼,稳重的装逼)1.判断奇偶数常用的(a%2!=0)位运算 if(a&1){奇数}原理:任

常用Oracle分析函数详解

学习步骤:1. 拥有Oracle EBS demo 环境 或者 PROD 环境2. copy以下代码进 PL/SQL3. 配合解释分析结果4. 如果网页有点乱请复制到TXT中查看 /*假设一个经理代表了一个部门*/SELECT emp.full_name,       emp.salary,       emp.manager_id,       row_number() over(PARTITION BY emp.manager_id ORDER BY emp.salary DESC) row

C#基础操作符详解(上)

本节内容: 1.操作符概览: 2.操作符的本质: 3.操作符与运算顺序 4.操作符详解. 1.操作符概览: 操作符(Operator)也译为”运算符” 操作符是用来操作数据的,被操作符操作的数据称为操作数(Operand) 表格从上往下优先级递减,同一行运算符的优先级一样一般按从左到右算, “=”赋值操作符,是先运算右边的值再运算左边的值,所以是最后运算的. 2.操作符的本质 ①操作符的本质是函数(即算法)的”简记法” 假如没有发明”+”只有Add函数,算式3+4+5将可以写成Add(Add(3

c语言位运算详解

位运算是指按二进制进行的运算.在系统软件中,常常需要处理二进制位的问题.C语言提供了6个位操作运算符.这些运算符只能用于整型操作数,即只能用于带符号或无符号的char,short,int与long类型. C语言提供的位运算符列表: 运算符含义描述 & 按位与      如果两个相应的二进制位都为1,则该位的结果值为1,否则为0 | 按位或      两个相应的二进制位中只要有一个为1,该位的结果值为1 ^ 按位异或    若参加运算的两个二进制位值相同则为0,否则为1 ~ 取反        ~

C语言位运算详解(转载)

转载自:http://www.cnblogs.com/911/archive/2008/05/20/1203477.html 位运算是指按二进制进行的运算.在系统软件中,常常需要处理二进制位的问题.C语言提供了6个位操作 运算符.这些运算符只能用于整型操作数,即只能用于带符号或无符号的char,short,int与long类型.C语言提供的位运算符列表:运算符 含义 描述& 按位与 如果两个相应的二进制位都为1,则该位的结果值为1,否则为0| 按位或 两个相应的二进制位中只要有一个为1,该位的结

Java的位运算符详解实例

Java的位运算符详解实例——与(&).非(~).或(|).异或(^).右移(>>).左移(<<).无符号右移(>>>) 位运算符主要针对二进制, 它包括了:“与”.“非”.“或”.“异或”."右移"."左移"."无符号右移". 从表面上看似乎有点像逻辑运算符, 但逻辑运算符是针对两个关系运算符来进行逻辑运算, 而位运算符主要针对两个二进制数的位进行逻辑运算. 下面详细介绍每个位运算符. 1.与运

16位汇编第六讲汇编指令详解第二讲

16位汇编第六讲汇编指令详解第二讲 1.比较指令 CMP指令 1.CMP指令是将目的操作数减去源操作数,按照定义相应的设置状态标志 2.CMP指令执行的功能与SUB指令(相减指令)一样,但是不同的是CMP指令之根据结果设置标志位 而不修改值 可以操作的指令格式 CMP reg,imm/reg/mem CMP mem,imm/reg 上面是CMP指令的语法,具体的也可以查询帮助文档,inter手册 inter手册查的办法 第一个框代表了CMP指令的所有语法 比如 reg,reg 表示可以比较寄存器