美文网首页
位运算与应用

位运算与应用

作者: 飞鹰雪玉 | 来源:发表于2021-05-13 10:12 被阅读0次

转载自http://blog.csdn.net/u012713968/article/details/50481680

二进制位运算

一,位运算基础
位运算(包括与,或,取反,异或,左移,右移等)是程序设计中的一个重要的领域。尤其是安全和底层开发中,除了指针的频繁使用之外,位运算是另一个非常频繁使用的领域。 因此,在求职面试中,位运算也是每年重点考查的知识点。首先,我们有必要复习一下C语言中位运算的一些基础计算方法。

1,与运算:&

与运算的操作符为&。2个数进行与运算时,就是将这2个数的二进制进行与操作, 只有当2个数对应的位都为1,该位运算结果为1,否则运算结果为0。即:1&1=1;1&0=0;0&0=0.

image.png

比如计算15&10,首先15的二进制为:1111,10的二进制为1010(二进制,十进制和十六进制转化方法: 点击这里 ),所以15&10为:

image.png

所以15&10=10。

2,或运算:|

或运算的操作符为|。2个数进行或运算时,就是将这2个数的二进制进行或操作, 只要2个数对应的位有一个为1,该位运算结果为1,否则运算结果为0。即:1|1=1;1|0=1;0|0=0.

image.png

比如计算15&10,首先15的二进制为:1111,10的二进制为1010,所以15|10为:

image.png

所以15|10=15。

3,取反运算:~

取反运算的操作符为,为单目运算符。取反运算符顾名思义,就是将一个整数中位为1的变成0,位为0的变成1。即:1=0;~0=1.

image.png

比如计算10,首先10的二进制为:1010,10为:

image.png

~10=5。

4,异或运算:^

异或运算的操作符为^。2个数进行异或运算时,就是将这2个数的二进制进行异或操作, 只要2个数对应的位相同,该位运算结果为0,否则运算结果为1。即:11=0;10=1;0^0=0.

image.png

比如计算1510,首先15的二进制为:1111,10的二进制为1010,所以1510为:

image.png

所以15^10=5。

5,右移运算符:>>

右移运算符为>>。将一个数a向右移动n位记为:a>>n。比如将12向右移动2位如何计算呢?12的二进制为00001100,那么右移动2位为:00000011,即3。 即12>>2为3。

右移动运算分为两种右移,一种为逻辑右移,在移动过程中,左边位用0填充。一种为算术右移,在移动过程中,左边用符号位来填充。 比如对于有符号数:10000011,对于逻辑右移,向右移动3位,那么左边用0填充,变成了:00010000。而对于算术右移,向右移动3位,那么左边用1(1为符号位)填充,变成了11110000。而对于01000011,算术右移3位,那么左边用0(0为符号位)填充,变成了00001000。 在C语言中,右移运算符为算术右移运算符,即左边用符号位来填充。

6,左移运算符:《

左移运算符为《。将一个数a向左移动n位记为:a《n。 比如将12向左移动2位如何计算呢?12的二进制为00001100,那么左移动2位为:00110000。 无论左移还是右移,都需要用0或者1去填充移动之后空位。在左移的过程中,右边一律用0去填充。左移就没有右移那样分为逻辑右移和算术右移。 比如,将10左移2位,由于10的二进制为:00001010,那么左移2位,右边用零填充的结果为:00101000。 将一个数左移N位相当于将一个数乘以2N,而将一个数右移N位相当于将这个数除以2N。

位运算运算符的优先级如下:(优先级由高到低排列)

image.png

而所有的C运算符的优先级与结合律如下图:(从图中可以看出,算术运算符的优先级高于《和》运算符)

image.png

一些常见的二进制位的变换操作如下图:

image.png

在实际的编程过程中,往往会用一个整数的不同位表示不同的数据信息。在访问该整数时,就需要通过位运算来获得或者改变整数的某几位数值。比如在Windows中创建文件时使用的Create数据结构:
struct
{
PIO_SECURITY_CONTEXT SecurityContext;
ULONG Options;
USHORT POINTER_ALIGNMENT FileAttributes;
USHORT ShareAccess;
ULONG POINTER_ALIGNMENT EaLength;
PVOID EaBuffer;
LARGE_INTEGER AllocationSize;
} Create;
通常会引用其中的Options如下:
Data->Iopb->Parameters.Create.Options
ULONG Options是一个Windows文件创建过程中的无符号长整数,指示在创建和打开文件时的不同选项。其中高8位指示了CreateDisposition参数(如FILE_OPEN,FILE_CREATE),低24位指示了CreateOptions参数(如FILE_DELETE_ON_CLOSE)。 为了得到CreateDisposition的值,采取下面的位操作:
(Data->Iopb->Parameters.Create.Options >> 24) & 0x000000ff;
将该整数右移24位,再与0xff做与操作,即可获得CreateDisposition的值。

二,位运算应用

1.任何一个数和0异或是它的本身,和自身异或为0:

a^0=a
a^a=0
利用上述性质,可以用来计算2个数的交换。
大家应该知道,在计算机里,两个数互相交换,需要定义一个中间的变量来参与交换。如:
int tmp;
int a=10;
int b=20;
tmp=a;
a=b;
b=tmp;
上述代码计算之后,a和b的值完成交换,a的值为20,b的值为10。
如果用异或运算来交换2个数,可以如下方法:
int a=10;
int b=20;
a=a^b;
b=a^b;
a=a^b;
上述运行之后,a和b依然完成了值的交换,但由于是异或位运算,所以效率比上面的代码要高。
证明:
a=10^20
b=ab=(1020)20=102020=100=10
a=ab=102010=101020=020=20
把上述代码,可以封装为一个交换2个数的函数如下:
void swap(int *a, int *b)
{
*a = *a ^ *b;
*b = *a ^ *b;
*a = *a ^ *b;
}

2.将整数的第n位置位或清零:

/#define BITN (1《n)
置位:a |= BITN;
清零:a &= ~BITN

3.清除整数a最右边的1。

方法:a & (a – 1)//该运算将会清除掉整数a二进制中最右边的1。
问题:如何判断判断整数x的二进制中含有多少个1?
分析:此题是微软公司的一道笔试题。下面用&运算来解决此题。 代码如下:
int func(int x )
{
int countx = 0;
while ( x )
{
countx++;
x = x&(x-1);
}
return countx;
}

4.用异或运算设计一个只有一个指针域的双向链表:
image.png

提示:
要实现该设计要求,需要记住链表的头结点和尾结点,并在链表结点的的next域存放前一个结点和后一个结点的异或值。即:
p->next=pl^pr;//头结点的左边结点为NULL,尾结点的右边结点为NULL。
在遍历的时候,从头结点往右遍历的方法:
pl=NULL;
p=Head;
while(p!=Tail)
{
pr=pl^(p->next);
pl=p;
p=pr;
}
从尾结点往左遍历的方法:
pr=NULL;
p=Tail;
while(p!=Tail)
{
pl=pr^(p->next);
pr=p;
p=pl;
}

5.计算下面表达式的值

(char)(127<<1)+1
(char)(-1>>1)+1
1<<2+3

解答:
(char)(127<<1)+1=(01111111<<1)+1=11111110+1=11111111=-1
(char)(-1>>1)+1=(11111111>>1)+1=11111111+1=0
1<<2+3=1<<(2+3)=1<<5=2^5=32(注意《和+的优先级)

相关文章

  • 位运算与应用

    转载自http://blog.csdn.net/u012713968/article/details/504816...

  • 位运算及其应用

    内容概要: 位运算基本操作 基于位运算的状态压缩 位运算经典应用 位运算解N皇后问题 位运算 符号描述规则&与1&...

  • 位运算应用

    取模 由于偶数的最低位为 0,奇数为 1,所以取模运算可以用位操作来代替。 取整 位掩码 通过定义这些选项,可以用...

  • 17.位运算基础及实战要点

    17.位运算基础及实战要点 位运算符 算数移位与逻辑移位 位运算的应用 为什么需要位运算 机器里的数字表示方式和存...

  • 位运算符

    常用位运算符: 左移与右移运算符应用举例: 注意:&和|既是逻辑运算符,也是位运算符。如果两侧操作数是boolea...

  • 按位与运算的应用(<< >>)

  • js 中位运算的应用

    按位运算符有6个: 按位与 & 按位或 | 按位异或 ^ 取反 ~ 右移 >> 左移 << 应用...

  • 位运算的应用

    位运算 程序中的所有数在计算机内存中都是以二进制的形式存储的。位运算说穿了,就是直接对整数在内存中的二进制位进行操...

  • C语言08- 位运算,宏定义,递归

    16:位运算 16.1:位运算概述 二进制与位运算 16.2:与(and):& 与运算:只有当2个数对应的位都为1...

  • C语言的位操作(Two)

    一、位运算赋值运算符 闲话就不多说,直接上图咯。 位运算赋值运算符 二、位运算应用 **eg:取一个整数a从右端开...

网友评论

      本文标题:位运算与应用

      本文链接:https://www.haomeiwen.com/subject/ozmpvktx.html