【转】位运算

【转】http://blog.chinaunix.net/uid-21411227-id-1826986.html

一.逻辑运算符 

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

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;
}

提示在某一平台进行程序开发时,首先要求了解此系统的基本数据类型的有效范围,对涉及的位运算进行评估,特别是要对边界数据进行检测,确保计算正确。

时间: 2024-10-30 22:14:31

【转】位运算的相关文章

位运算

位运算的实际应用场景 http://blog.csdn.net/zmazon/article/details/8262185

POJ 1781 In Danger Joseph环 位运算解法

Joseph环,这次模固定是2.假设不是固定模2,那么一般时间效率是O(n).可是这次由于固定模2,那么能够利用2的特殊性,把时间效率提高到O(1). 规律能够看下图: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQva2VuZGVuMjM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" > 具体具体解析请看大师Knuth的Concrete m

位运算总结&amp;拾遗

JavaScript 位运算总结&拾遗 最近补充了一些位运算的知识,深感位运算的博大精深,此文作为这个系列的总结篇,在此回顾下所学的位运算知识和应用,同时也补充下前文中没有提到的一些位运算知识. 把一个数变为大于等于该数的最小的2的幂 一个数为2的幂,那么该数的二进制码只有最高位是1. 根据这个性质,我们来举个栗子,比如有数字10,转为二进制码后为: 1 0 1 0 我们只需把 0 bit的位置全部用1填充,然后再把该二进制码加1就ok了.而x | (x + 1)正好可以把最右边的0置为1,可是

Java I/O : Bit Operation 位运算

Writer      :BYSocket(泥沙砖瓦浆木匠) 微         博:BYSocket 豆         瓣:BYSocket FaceBook:BYSocket Twitter    :BYSocket 泥瓦匠喜欢Java,文章总是扯扯Java. I/O 基础,就是二进制,也就是Bit. 一.Bit与二进制 什么是Bit(位)呢?位是CPU处理或者数据存储最小的单元.类似于很小很小的开关,一开一关,表示为1或者0.所以,这就是计算机处理任何数据的"细胞",要谨记.

mysql位运算

1.MOD(X1,X2) 求余运算,返回余数同"%" 2.X1 DIV X2 除法运算返回商,同"/" 3.如果除数为0,那么结果为NULL. 4.<=>和= 是一样的,也是用来判断操作数是否相等的.不同的是<=>可以用来判断null,=不能判断null. 例:select null<=>null 结果1 逻辑运算符 1.与&&或and:所有操作数不为0且不为null时,结果为1,任何一操作数为0,结果为0,存在一

位运算之 C 与或非异或

位运算比较易混: 位运算之 C 与或非异或 与运算:& 两者都为1为1,否则为0 1&1=1,  1&0=0,  0&1=0,  0&0=0 或运算:| 两者都为0为0,否则为1 1|1 = 1,  1|0 = 1,  0|1 = 1, 0|0 = 0 非运算:~ 1取0,0取1 ~1 = 0, ~0 = 1 ~(10001) = 01110 异或运算:^ 两者相等为0,不等为1(易混淆) 1^1=0, 1^0=1, 0^1=1, 0^0=0 位移操作符:<&

Java的位运算

左移位操作 左移位运算的符号为[<<],左移位运算符左面的操作元称作被移位数,右面的操作数称作移位量. 左移位运算是双目运算符,操作元必须是整型类型的数据,其移动过程是:[a << n]运算的过程是通过将a的所有位都左移n位,每左移一个位,左边的最高位上的0或1被移出丢弃,并用0填充右边的低位 注意: 如果a是byte.short或int型数据,总是先计算出n%32的结果m,然后进行a<<m运算 对于long型数据,总是先计算出n%64的结果m,然后进行a <&l

常见的位运算

位运算主要有:|   &   ^    ~ & 这个是只要有0,则0 | 这个只要有1,则1 ^异或运算,只要不同则为1 ~全部相反 参与位运算首先要将数值化作为二进制补码,方可参与运算 >>                                               >>>                                << 有符号右移                                无符号右移   

C位运算笔记(根据网上内容整理)1

什么是位运算?    程序中的所有数在计算机内存中都是以二进制的形式储存的.位运算说穿了,就是直接对整数在内存中的二进制位进行操作.由于位运算直接对内存数据进行操作,不需要转成十进制,因此处理速度非常快. 各种位运算的使用 === 1. and运算 ===(同真为真) and运算通常用于二进制取位操作,例如一个数 and 1的结果就是取二进制的最末位.这可以用来判断一个整数的奇偶,二进制的最末位为0表示该数为偶数,最末位为1表示该数为奇数. === 2. or运算 ===(一真为真) or运算通

位运算和关于两个数交换的多种方法

我们知道,位运算在计算中有着广泛的应用. 在计算机的各种编程语言中位运算也是一种不可缺少的运算,尤其是在计算机的底层实现代码中. 以下我们就来介绍一下位运算. 1.左移运算<<  左移右移都是移动二进制数 0000-0000 0000-0000 0000-0000 0000-1100     =12 向左移动一位变为(右边缺几位就补几个0) 0000-0000 0000-0000 0000-0000 0001 1000       =24 再向左移一位 0000-0000 0000-0000